在 OCaml 中调用惰性列表函数

Call lazy-list function in OCaml

如何调用以下函数来计算从 1 到 100 的数字?

type 'a llist = Cons of 'a * (unit -> 'a llist)
let rec lnat n = Cons (n, fun () -> lnat (n+1))

调用 lnat 1 得到以下信息:

lnat 1;;
- : int llist = Cons (1, <fun>)

但是如何计算以下数字?

如果目标是将(an 的有限前缀)llist 转换为普通的 list,我们可以使用简单的递归辅助函数来实现。

let rec take n (Cons (x, xs)) =
  if n = 0 then [] else x :: take (n - 1) (xs ())

用作

# take 100 (lnat 1);;
- : int list =
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21;
 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39; 40;
 41; 42; 43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59;
 60; 61; 62; 63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78;
 79; 80; 81; 82; 83; 84; 85; 86; 87; 88; 89; 90; 91; 92; 93; 94; 95; 96; 97;
 98; 99; 100]

表示中的 llist 严格存储第一个值,然后将其余计算隐藏在采用 () 的函数后面。由于该函数采用 ()(即没有实参),它唯一的选择(除了产生副作用,我认为在这种情况下这是意想不到的行为)是产生一个常量值。

所以它实际上只是一个无限列表,其中函数部分“保护”列表的其余部分免于淹没您的计算机内存。要访问以下元素,请将函数应用于 (),类型为 unit 的唯一有效值。