F#创建因子函数,不带递归,库函数或循环

Chr*_*oph 3 f#

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

Ruby中的代码

fx = ->(improver) {
  improver.(improver)
}.(
   ->(improver) {
     ->(n) { n.zero ? 1 : n * improver.(improver).(n-1) }
   }
   )
Run Code Online (Sandbox Code Playgroud)

我试图表达这种方法F#

let fx =
    (fun improver -> improver(improver))(
    fun improver ->
             fun n ->
             if n = 0 then 1
             else n * improver(improver(n - 1)))
Run Code Online (Sandbox Code Playgroud)

我现在被困在了

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

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

编辑:

*没有rec关键字

kvb*_*kvb 5

ML样式类型推断的语言将无法推断该术语的类型fun improver -> improver improver; 它们首先假设'a -> 'blambda定义的类型(对于一些未确定的类型'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))
Run Code Online (Sandbox Code Playgroud)

  • @ChristophAlrich - Ruby是一种动态语言,因此根本没有静态类型.这样做的好处是不需要类型注释和拆箱操作,但缺点是编译器永远不会告诉您是否已将操作应用于不兼容的值(您将获得运行时异常). (2认同)