为什么这个惰性求值函数在 OCaml 中不起作用

Why is this lazy evaluation function not working in OCaml

我编写这个示例是为了更好地理解 OCaml 中惰性求值的工作原理 - 使用 thonks。

let rec imp n = fun () -> imp(n*n);; 

我对惰性求值/thonks 的理解是 impl 会 和我打电话一样频繁地平方初始数字 imp ().

但是此函数 imp 会引发以下错误:

---
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
---

编译器告诉您您的函数具有递归类型。如果在 运行 ocaml:

时提供 -rectypes ,则可以使用递归类型
$ ocaml -rectypes
    OCaml version 4.10.0

# let rec imp n = fun () -> imp(n*n);;
val imp : int -> (unit -> 'a as 'a) = <fun>

另一方面,我认为您的功能并不像您想象的那样工作。或者至少我看不到任何方法来找出它最近计算的数字。我猜你必须相信它正在计算越来越大的数字。

我会研究 Seq 模块并使用它。

这是一个演示您要实现的目标的示例:

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);

请注意函数中用于解决类型问题的类型构造函数Func incr_by_2。

下面是一个使用 Seq 模块展开函数的例子。

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()