Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Functional programming 惰性求值(OCaml)的执行_Functional Programming_Ocaml_Lazy Evaluation - Fatal编程技术网

Functional programming 惰性求值(OCaml)的执行

Functional programming 惰性求值(OCaml)的执行,functional-programming,ocaml,lazy-evaluation,Functional Programming,Ocaml,Lazy Evaluation,我正试图在懒惰评估的执行下工作 我创建了一个lazy列表类型和相应的map函数 type 'a zlist = 'a node_t lazy_t and 'a node_t = Empty | Node of 'a * 'a zlist let rec zlist_of_list l = lazy ( match l with | [] -> Empty | hd::tl -> Printf.printf "transforming %d\n" hd;Node

我正试图在懒惰评估的执行下工作


我创建了一个
lazy列表
类型和相应的
map
函数

type 'a zlist = 'a node_t lazy_t
and 'a node_t = Empty | Node of 'a * 'a zlist

let rec zlist_of_list l = lazy (
  match l with
    | [] -> Empty
    | hd::tl -> Printf.printf "transforming %d\n" hd;Node (hd, zlist_of_list tl)
)

let rec list_of_zlist zl = 
  match Lazy.force zl with
    | Empty -> []
    | Node (hd, tl) -> hd::(list_of_zlist tl)

let rec map_z f zl = lazy (
  match Lazy.force zl with
    | Empty -> Empty
    | Node (hd, tl) -> Node (f hd, map_z f tl)
)
第一个问题:

根据我的理解,
lazy
只是将事物封装在
()中,而不立即执行

因此,对于函数
zlist\u of_list
,整个

match l with
  | [] -> Empty
  | hd::tl -> Node (hd, zlist_of_list tl)
将被延迟,当应用
zlist\u of_list
时,不会执行任何一位,
map\u z

我说得对吗


下面,我尝试执行双重
惰性映射

let f1 x = Printf.printf "%d\n" x; x

let f2 x = Printf.printf " %d\n" (-x); (-x)

let zl = zlist_of_list [1;2;3]

let zl_m2 = map_z f2 (map_z f1 zl)

let _ = list_of_zlist zl_m2
结果是

transforming 1
1
 -1
transforming 2
2
 -2
transforming 3
3
 -3
这个问题我不明白。似乎是按列执行,而不是按行执行。我想应该是的

  • 每个元素首先被转换
  • 然后将f1映射到每个元素
  • f2被映射到每个元素
  • 第二个问题:


    为什么通过lazy,执行顺序会变成这样?

    对于您的第一个问题:没错,
    map_z
    将返回一个thunk,计算列表的下一部分,而不是列表本身。特别是,
    map_z
    定义中的递归调用在强制执行之前不会下降到列表的其余部分-您可以从
    map_z
    的结果中获取一个转换后的元素,而无需计算其余部分

    这也是第二个问题的答案:您看到一个元素被转换,然后传递到
    f1
    ,然后传递到
    f2
    的原因是,在每个步骤中,您都从惰性列表中提取一个元素,而其他元素保持挂起状态


    这就是懒惰列表的全部意义!这样做很有用,因为它提供了一种相当自然的方式来编写无限(或非常大)的列表。如果在使用元素之前必须先计算整个列表,那么它就不是一个真正的惰性数据结构。

    对于第一个问题:没错,
    map_z
    将返回一个thunk,计算列表的下一部分,而不是列表本身。特别是,
    map_z
    定义中的递归调用在强制执行之前不会下降到列表的其余部分-您可以从
    map_z
    的结果中获取一个转换后的元素,而无需计算其余部分

    这也是第二个问题的答案:您看到一个元素被转换,然后传递到
    f1
    ,然后传递到
    f2
    的原因是,在每个步骤中,您都从惰性列表中提取一个元素,而其他元素保持挂起状态

    这就是懒惰列表的全部意义!这样做很有用,因为它提供了一种相当自然的方式来编写无限(或非常大)的列表。如果在使用元素之前必须先计算整个列表,那么它就不是真正的惰性数据结构