Reputation: 410
I made this example up to better understand how lazy evaluation works in OCaml - using thonks.
let rec imp n = fun () -> imp(n*n);;
My understanding of lazy evaluation / thonks is that impl will
square an initial number as often as I'm calling
imp ()
.
However this function imp
raises the following error:
---
let rec imp n acc = fun()->(***imp (n\*acc)***);;
This expression has type int -> unit -> 'a
but an expression was expected of type 'a
The type variable 'a occurs inside int -> unit -> 'a
---
Upvotes: 1
Views: 174
Reputation: 2829
I would investigate the Seq module and use that.
Here's an example that demonstrates what you are trying to accomplish:
type func = Func of (unit -> int * func)
let rec incr_by_2 x =
let ans = x + 2 in
(ans, Func(fun () -> incr_by_2 ans))
let ans = incr_by_2 10
let () =
match ans with
| (d, Func f) -> print_endline(string_of_int d);
match f() with
| (d, Func f) -> print_endline(string_of_int d);
match f() with
| (d, _) -> print_endline(string_of_int d);
Please note the type constructor Func which is used to resolve the type problem in the function incr_by_2.
Here's an example using the Seq module's unfold function.
type func = Func of (unit -> int * func)
let rec incr_by_2 x =
let ans = x + 2 in
(ans, Func(fun () -> incr_by_2 ans))
let seq x =
Seq.unfold
(
fun (d, Func f) ->
if d < x
then
Some(d, f())
else
None
)
(incr_by_2 10)
let () =
(seq 100) |> Seq.iter (Printf.printf "%d\n"); print_newline()
Upvotes: 3
Reputation: 66803
The compiler is telling you that your function has a recursive type. You can work with recursive types if you supply -rectypes
when you run ocaml
:
$ ocaml -rectypes
OCaml version 4.10.0
# let rec imp n = fun () -> imp(n*n);;
val imp : int -> (unit -> 'a as 'a) = <fun>
On the other hand I don't think your function works like you think. Or at least I don't see any way to find out what number it has recently calculated. You'll have to take it on faith that it is calculating larger and larger numbers, I guess.
Upvotes: 6