x,f x,f(f x)的懒惰列表



Batteries.LazyList允许一个定义懒惰列表。我想定义一个由xf xf (f x)f (f (f x))等组成的懒惰列表。

根据模块文档中的注释,看来from_loop是我想要的功能:

" from_loop data next从将next应用于data的连续结果中创建了(可能是无限的(懒惰列表,然后对结果等。"

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

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 LazyList.t?元素的类型不应该与next函数的参数类型相同吗?该功能的描述对我来说并不清楚答案。


如果有帮助,我对我要做的事情的概念来自Clojure的iterate。在Clojure中,我可以创建上述定义:

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

传递给from_loop的功能必须返回一对。该对的第一个元素是您要返回的值。该对的第二个元素是稍后在。

您的代码:

(fun n -> n + 1)

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

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

(这将从0开始返回列表,我认为这是您想要的。(

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

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

事实证明,我真正想要的功能是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]

相关内容

  • 没有找到相关文章

最新更新