这不起作用:
let rec fix f = f (fix f)
解决方案是添加一个额外的参数:
let rec fix f x = f (fix f) x
有没有办法使用lazy
和Lazy.force
代替?
答案 0 :(得分:5)
您的原始fix
需要'a -> 'a
:
> let rec fix f = f (fix f);;
val fix : ('a -> 'a) -> 'a
如果您选择Lazy<'a> -> 'a
,那么您可以写下:
> let rec fix f = lazy f (fix f);;
val fix : (Lazy<'a> -> 'a) -> Lazy<'a>
这允许f
在不需要的情况下不评估其参数,因此递归可以在运行时终止。
如果您希望结果为'a
类型,则只需强制执行最终结果:
> let rec fix' f = lazy f (fix' f);;
val fix' : (Lazy<'a> -> 'a) -> Lazy<'a>
> let fix f = (fix' f).Value;;
val fix : (Lazy<'a> -> 'a) -> 'a
例如,这里是阶乘函数:
> fix (fun f n -> if n > 1 then n * f.Value (n-1) else 1) 4;;
val it : int = 24