如何编写一个函数,在每次迭代时将可变数量的元素附加到惰性列表中?
How to write a function that appends a variable number of elements to a lazy list with each iteration?
激发灵感的问题是:编写一个惰性列表,其元素是 0 和 1 的所有可能组合,即 [0]、[1]、[0;0]、[0;1] 等。
在 OCaml 中工作,我编写了辅助函数,用于生成给定 n 的长度为 n+1 的排列列表,并将列表转换为惰性列表。问题来自以下代码块中的最终函数:
type 'a seq =
| Nil
| Cons of 'a * (unit -> 'a seq)
let rec adder = function
| [] -> []
| [[]] -> [[0];[1]]
| xs::ys -> (0::xs)::(1::xs)::(adder ys)
let rec listtoseq = function
| [] -> Nil
| xs::ys -> Cons(xs, fun () -> listtoseq ys)
let rec appendq xq yq =
match xq with
| Nil -> yq
| Cons (x, xf) -> Cons (x, fun() -> appendq (xf ()) yq)
let genlist xs = appendq (listtoseq xs) (genlist (adder xs))
调用 genlist [[0];[1]] 导致堆栈溢出。问题似乎是因为 genlist 是一个无限循环我想延迟评估,但 appendq 需要评估才能工作。
如果这是一次将一个元素添加到惰性列表中的问题,我可以解决它,但我认为困难在于必须一次添加每组长度为 n 的排列,因此我除了使用追加函数之外不知道任何其他解决方案。
查看您的问题的一种方法是 appendq
不够懒惰。如果你用这种类型定义一个函数 appendqf
,你可以使事情工作:
'a seq -> (unit -> 'a seq) -> 'a seq
换句话说,第二个参数不是序列。这是一个returns一个序列的函数。
(请注意,此类型 unit -> 'a seq
是实际出现在 Cons
中的类型。)
我试过了,对我有用。
激发灵感的问题是:编写一个惰性列表,其元素是 0 和 1 的所有可能组合,即 [0]、[1]、[0;0]、[0;1] 等。
在 OCaml 中工作,我编写了辅助函数,用于生成给定 n 的长度为 n+1 的排列列表,并将列表转换为惰性列表。问题来自以下代码块中的最终函数:
type 'a seq =
| Nil
| Cons of 'a * (unit -> 'a seq)
let rec adder = function
| [] -> []
| [[]] -> [[0];[1]]
| xs::ys -> (0::xs)::(1::xs)::(adder ys)
let rec listtoseq = function
| [] -> Nil
| xs::ys -> Cons(xs, fun () -> listtoseq ys)
let rec appendq xq yq =
match xq with
| Nil -> yq
| Cons (x, xf) -> Cons (x, fun() -> appendq (xf ()) yq)
let genlist xs = appendq (listtoseq xs) (genlist (adder xs))
调用 genlist [[0];[1]] 导致堆栈溢出。问题似乎是因为 genlist 是一个无限循环我想延迟评估,但 appendq 需要评估才能工作。
如果这是一次将一个元素添加到惰性列表中的问题,我可以解决它,但我认为困难在于必须一次添加每组长度为 n 的排列,因此我除了使用追加函数之外不知道任何其他解决方案。
查看您的问题的一种方法是 appendq
不够懒惰。如果你用这种类型定义一个函数 appendqf
,你可以使事情工作:
'a seq -> (unit -> 'a seq) -> 'a seq
换句话说,第二个参数不是序列。这是一个returns一个序列的函数。
(请注意,此类型 unit -> 'a seq
是实际出现在 Cons
中的类型。)
我试过了,对我有用。