F#中的定点组合器

时间:2014-02-08 12:25:02

标签: f#

这不起作用:

let rec fix f = f (fix f)

解决方案是添加一个额外的参数:

let rec fix f x = f (fix f) x

有没有办法使用lazyLazy.force代替?

1 个答案:

答案 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