List Ocaml列表:实现append和map函数

List Ocaml列表:实现append和map函数,list,functional-programming,map,ocaml,lazy-evaluation,List,Functional Programming,Map,Ocaml,Lazy Evaluation,我目前正在尝试扩展朋友的OCaml程序。这是一些数据分析所需的大量函数集合。。因为我不是一个真正的OCaml高手,所以我目前被困在一个(对我来说)奇怪的列表实现上: type 'a cell = Nil | Cons of ('a * 'a llist) and 'a llist = (unit -> 'a cell);; 我发现它实现了某种“懒惰”列表,但我完全不知道它到底是如何工作的。我需要基于上述类型实现一个Append和一个Map函数。有人知道怎么做吗 任何帮助都将不胜感

我目前正在尝试扩展朋友的OCaml程序。这是一些数据分析所需的大量函数集合。。因为我不是一个真正的OCaml高手,所以我目前被困在一个(对我来说)奇怪的列表实现上:

type 'a cell = Nil
    | Cons of ('a * 'a llist)
and 'a llist = (unit -> 'a cell);;
我发现它实现了某种“懒惰”列表,但我完全不知道它到底是如何工作的。我需要基于上述类型实现一个Append和一个Map函数。有人知道怎么做吗

任何帮助都将不胜感激

let rec append l1 l2 = 
    match l1 () with
        Nil -> l2 | 
        (Cons (a, l)) -> fun () -> (Cons (a, append l l2));;

let rec map f l =
    fun () -> 
        match l () with
            Nil -> Nil | 
            (Cons (a, r)) -> fun () -> (Cons (f a, map f r));;
这种惰性列表实现的基本思想是,每个计算都通过fun()->x封装在一个函数中(技术术语是闭包)。
表达式x仅在函数应用于()时(单位值,不包含任何信息)才计算。

请注意,函数闭包本质上等同于惰性值:

lazy n : 'a Lazy.t    <=>    (fun () -> n) : unit -> 'a
force x : 'a          <=>    x () : 'a
i、 例如,一个惰性单元格值

根据上述定义,map实现可能更有意义

let rec map f lst =
  match force lst with
    | Nil -> lazy Nil
    | Cons (hd,tl) -> lazy (Cons (f hd, map f tl))
将其转换回闭包:

let rec map f lst =
  match lst () with
    | Nil -> (fun () -> Nil)
    | Cons (hd,tl) -> (fun () -> Cons (f hd, map f tl))
与append类似

let rec append a b =
  match force a with
    | Nil -> b
    | Cons (hd,tl) -> lazy (Cons (hd, append tl b))
变成

let rec append a b =
  match a () with
    | Nil -> b
    | Cons (hd,tl) -> (fun () -> Cons (hd, append tl b))
我通常更喜欢使用
lazy
语法,因为它使事情变得更清楚

还要注意的是,延迟暂停和闭包并不是完全等价的。比如说,

let x = lazy (print_endline "foo") in
  force x;
  force x
印刷品

foo
foo
foo
鉴于

let x = fun () -> print_endline "foo" in
  x ();
  x ()
印刷品

foo
foo
foo

区别在于
force
只计算表达式的值一次。

是的,列表可以是无限的。其他答案中给出的代码将附加到无限列表的末尾,但是没有一个程序可以编写,可以观察无限列表后面附加的内容