| open Core.Std | |
| let values_of_line line = | |
| let fields = String.split ~on:',' line in | |
| List.map ~f:Float.of_string fields | |
| let add_to totals values = | |
| match totals with | |
| | [] -> values | |
| | _ -> | |
| if List.length totals = List.length values then | |
| List.map2_exn ~f:(+.) totals values | |
| else failwith "Inconsistent-length rows" | |
| let sum_channel chan = | |
| let folder tot line = add_to tot (values_of_line line) in | |
| In_channel.fold_lines ~f:folder ~init:[] chan | |
| let sum_and_print_file filename = | |
| In_channel.with_file filename | |
| ~f:(fun chan -> | |
| let result = sum_channel chan in | |
| print_string | |
| ((String.concat ~sep:"," (List.map ~f:Float.to_string result)) ^ "\n")) | |
| let main () = | |
| match Sys.argv with | |
| | [| _; filename |] -> sum_and_print_file filename | |
| | _ -> failwith "Exactly 1 filename must be given" | |
| let () = main () |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment
Hide comment
keleshev
commented
Feb 19, 2016
|
I tried to use Core as well and independently got a very similar solution: open Core_kernel.Std
let (>>) f g x = g (f x)
module Row = struct
let parse_exn = String.split ~on:',' >> List.map ~f:Float.of_string
let to_string = List.map ~f:Float.to_string >> String.concat ~sep:","
let print = to_string >> print_endline
end
let folder sum line =
let row = Row.parse_exn line in
match sum with
| [] -> row
| _ when List.length sum = List.length row -> List.map2_exn ~f:(+.) sum row
| _ -> failwith "Inconsistent-length rows"
let () = match Sys.argv with
| [|_; filename|] ->
In_channel.(with_file filename ~f:(fold_lines ~init:[] ~f:folder))
|> Row.print
| _ -> failwith "Exactly 1 filename must be given" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried to use Core as well and independently got a very similar solution: