可以使用let rec创建无限的循环列表,而无需求助于可变引用:
let rec xs = 1 :: 0 :: xs ;;
但是我可以使用相同的技术来编写一个接收有限列表并返回其无限循环版本的函数吗?我尝试写作
let rec cycle xs =
let rec result = go xs and
go = function
| [] -> result
| (y::ys) -> y :: go ys in
result
;;
但是出现了以下错误
错误:不允许这种表达式作为`let rec'的右侧
您的代码有两个问题:
result = go xs
是非法形式 let rec
上面的代码被编译器拒绝了,因为您不能在右侧写一个可能导致递归计算的表达式let rec
(请参阅OCaml中let rec的限制)。
即使解决了问题,您仍然遇到问题:cycle
无法完成工作:
let rec cycle xs =
let rec go = function
| [] -> go xs
| y::ys -> y :: g ys
in
go xs;;
cycle [1;2];;
cycle [1;2]
由于堆栈溢出而失败。
在OCaml中,let rec
仅当其定义为“静态”且不执行任何计算时,才可以定义循环结构。let rec xs = 1 :: 0 :: xs
就是这样一个例子:(::)
不是函数而是构造函数,它只是构造数据结构。另一方面,cycle
执行一些代码执行以动态创建结构并且它是无限的。恐怕您不能像cycle
在OCaml中那样编写函数。
如果要cycle
在OCaml等数据中引入一些循环,可以使用惰性结构来防止立即无限循环(例如Haskell的惰性列表),或者使用变体通过替换来构成循环。OCaml的列表不是惰性的也不是可变的,因此您不能编写动态构造循环列表的函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句