1

Batteries.LazyList允许定义惰性列表。我想定义一个包含x, f x, f (f x),f (f (f x))等 的惰性列表。

根据模块文档中的评论,这似乎from_loop是我想要的功能:

“从应用到from_loop data next的连续结果创建一个(可能是无限的)惰性列表,然后应用到结果等。”nextdata

这个描述表明,如果我想要一个非负整数的惰性列表,例如,我可以这样定义它:

let nat_nums = from_loop 0 (fun n -> n + 1)

但是,这失败了,因为签名from_loop

'b -> ('b -> 'a * 'b) -> 'a LazyList.t

所以next函数有签名('b -> 'a * 'b)。在 utop 中,错误消息下划线n + 1并说

Error: This expression has type int but an expression was expected of type 'a * int

我不明白'a应该是什么。为什么next函数应该返回一对?为什么列表的类型应该是 a 'a LazyList.t?元素的类型不应该与函数参数的类型相同next吗?该功能的描述并没有让我清楚地知道答案。


如果它有帮助,我对我正在尝试做的事情的概念来自 Clojure 的iterate. 在 Clojure 中,我可以像这样创建上述定义:

(def nat-nums (iterate (fn [n] (+ n 1)) 0))
4

2 回答 2

2

传递给的函数from_loop必须返回一对。该对的第一个元素是您要返回的值。该对的第二个元素是稍后计算下一个元素所需的状态。

你的代码:

(fun n -> n + 1)

只是计算惰性列表的下一个元素,它不会返回下一次调用所需的状态。像这样的东西是想要的:

(fun n -> (n, n + 1))

(这将返回一个以 0 开头的列表,我认为这是您想要的。)

此公式比您的 clojure 示例更灵活,因为它允许您维护与返回值不同的任意状态。状态是'b你给的类型中的类型from_loop

我现在没有电池,所以我不能试试这个。但我认为根据类型是正确的。

于 2017-04-30T05:44:54.310 回答
0

事实证明,我真正想要的功能是LazyList.seq,不是from_loop。虽然from_loop有其用途,seq但更简单并且可以满足我的需求。唯一的技巧是您必须提供第三个参数,它是一个终止测试,当列表应该结束时返回 false。我想要一个无限的列表。可以使用始终返回 true 的终止函数来创建它:

let nat_nums = seq 0 (fun n -> n + 1) (fun _ -> true);;
LazyList.to_list (LazyList.take 8 nat_nums);;
- : int list = [0; 1; 2; 3; 4; 5; 6; 7]
于 2017-11-10T05:08:34.997 回答