ensure unfold is tailrec

This commit is contained in:
Simon Cruanes 2023-12-05 12:04:55 -05:00
parent 73e68dae7c
commit 7fcf26963b
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
2 changed files with 40 additions and 5 deletions

View file

@ -281,11 +281,6 @@ let fold_flat_map_i f acc l =
in
aux f acc 0 [] l
let rec unfold f seed =
match f seed with
| None -> []
| Some (v, next) -> v :: unfold f next
[@@@iflt 5.1]
(* keep this because it's tailrec for < 5.1 *)
@ -314,6 +309,32 @@ let init len f =
else
direct_ 0
let rec unfold_kont f seed k =
match f seed with
| None -> k []
| Some (v, next) ->
let k' tl = v :: tl in
unfold_kont f next k'
let[@inline] unfold f seed =
let rec direct i f seed =
if i = 0 then
unfold_kont f seed (fun x -> x)
else (
match f seed with
| None -> []
| Some (v, next) -> v :: direct (i - 1) f next
)
in
direct 100 f seed
[@@@else_]
let[@tail_mod_cons] rec unfold f seed =
match f seed with
| None -> []
| Some (v, next) -> v :: unfold f next
[@@@endif]
let rec compare f l1 l2 =

View file

@ -141,6 +141,20 @@ in
unfold f 0 = [ 0; 2; 4; 6; 8; 10 ]
;;
t @@ fun () ->
let l =
unfold
(fun n ->
if n < 1_000_000 then
Some (n, n + 1)
else
None)
0
in
assert_equal ~printer:Q.Print.int (List.length l) 1_000_000;
true
;;
t @@ fun () -> init 0 (fun _ -> 0) = [];;
t @@ fun () -> init 1 (fun x -> x) = [ 0 ];;
t @@ fun () -> init 1000 (fun x -> x) = 0 -- 999;;