functional programming - Limit recursion to the first three elements of list of floats -
i'm new functional programming (reasonml / ocaml).
i have list of floats. want first 3 non-zero items of list , no more. items can positive, negative, , zero.
how can recursion limited until first 3 non-zero floats extracted?
i thinking of doing like:
switch (list) { | [first, second, third, ...rest] => (first +. second +. third) /. 3.0 | _ => 0.0 };
but how can guarantee first
, second
, , third
non-zero floats? , if are, discard them recursively until 3 non-zero floats found -- or return 0.0
.
a nicer way using recursion make more generic: instead of finding 3 first non-zero, let's find n
first non-zero.
below ocaml implementation, don't know reason.
let rec find_n l n ~f = if n = 0 [] else match l | [] -> failwith "cannot find enough items" | h::t -> if f h h :: (find_n t (n-1) ~f) else find_n (t n ~f)
here's function's signature:
val find_n : 'a list -> int -> f:('a -> bool) -> 'a list = <fun>
there's lot going on here, it's not bad. logic here following:
if want 3 items list:
- if head matches, need 2 items in tail.
- else, still need 3 items in tail.
everything else additional logic:
- if i'm looking 0 items, i'm done.
- if list empty , still need more items, failed.
a word tail-recursion
unfortunately, above implementation not tail-recursive, means fail on large lists. common technique make function tail-recursive use accumulator (acc
in code below) store intermediate result.
then, encapsulate logic in local helper function (often called loop
or aux
) accumulator doesn't show in function's signature.
let find_n l n ~f = let rec loop l' n' acc = if n' = 0 acc else match l' | [] -> failwith "cannot find enough items" | h::t -> if f h loop t (n' - 1) (h::acc) else loop t n' acc in loop l n []
Comments
Post a Comment