F#创建没有递归,库函数或循环的因子函数

在这段关于35:14函数式编程的视频中,Jim Weirich写了一个函数来计算阶乘,而不使用递归,库函数或循环:在这里查看Ruby代码的图像

Ruby中的代码

fx = ->(improver) {
  improver.(improver)
}.(
   ->(improver) {
     ->(n) { n.zero ? 1 : n * improver.(improver).(n-1) }
   }
   )

我试图表达这种方法F#

let fx =
    (fun improver -> improver(improver))(
    fun improver ->
             fun n ->
             if n = 0 then 1
             else n * improver(improver(n - 1)))

我目前被困在

类型不匹配。 期待一个'a,但给一个'a - >'b
当统一''a'和''a - >'b'时,结果类型将是无限的。

我似乎无法找到正确的类型注释或其他表达函数的方式

编辑:

*没有rec关键字


使用ML风格类型推断的语言将无法推断术语fun improver -> improver improver的类型fun improver -> improver improver ; 他们首先假定类型'a -> 'b为一个lambda定义(对于某些未确定的类型'a'b ),因此参数improver器的类型为'a ,但是它被应用于自身以给出结果类型'b ),所以improver必须同时具有类型'a -> 'b 。 但是在F#类型系统中,没有办法将这些类型统一起来(并且在简单类型的lambda演算中根本没有办法给这个术语一个类型)。 我对您在评论中链接的问题的回答涵盖了一些解决方法。 @desco已经给出了其中之一。 另一个是:

let fx = (fun (improver:obj->_) -> improver improver)
         (fun improver n -> 
              if n = 0 then 1 
              else n * (improver :?> _) improver (n-1))

这是作弊,但你可以使用类型

type Self<'T> = delegate of Self<'T> -> 'T
let fx1 = (fun (x: Self<_>) -> x.Invoke(x))(Self(fun x -> fun n -> if n = 0 then 1 else x.Invoke(x)(n - 1) * n))

type Rec<'T> = Rec of (Rec<'T> -> 'T)
let fx2 = (fun (Rec(f ) as r) -> f r)(Rec(fun ((Rec f) as r) -> fun n -> if n = 0 then 1 else f(r)(n - 1) * n))
链接地址: http://www.djcxy.com/p/80549.html

上一篇: F# Create Factorial function without recursion, library functions or loops

下一篇: tail call optimization for tail recursive lambda function