【问题标题】:y-combinator in StandardMLStandardML 中的 y 组合器
【发布时间】:2017-04-02 22:35:14
【问题描述】:

我知道我可以像这样在 SML 中编写 y-combinator: 首先声明一个新的数据类型来绕过由于循环导致的类型不匹配。

datatype 'a mu = Roll of ('a mu -> 'a)
val unroll = fn Roll x => x

现在您可以轻松定义 y 组合器:

val Y = fn f => (fn x => fn a => f (unroll x x) a)
          (Roll (fn x => fn a => f (unroll x x) a)))

那么你就完成了,你可以这样使用它:

val f = Y (fn f => fn n => if n = 0 then 1 else n * f (n-1))

我的问题是:还有其他方法可以在 SML 中实现 y 组合器吗?

【问题讨论】:

    标签: functional-programming sml y-combinator


    【解决方案1】:

    您当然可以使用内置递归本身,例如

    fun Y f = f (fn x => Y f x)
    

    fun Y f x = f (Y f) x
    

    您也可以像使用数据类型一样使用异常,但只能单态:

    exception Roll of exn -> int -> int
    val unroll = fn Roll x => x
    fun Y f = (fn x => fn a => f (unroll x x) a) (Roll (fn x => fn a => f (unroll x x) a))
    

    但我相信还有关于涵盖它的参考资料。

    编辑:实际上,您可以使用 local 异常使其具有多态性:

    fun Y f : 'a -> 'b =
      let
        exception Roll of exn -> 'a -> 'b
        val unroll = fn Roll x => x
      in
        (fn x => fn a => f (unroll x x) a) (Roll (fn x => fn a => f (unroll x x) a))
      end
    

    【讨论】:

    • 你不能,因为为此所需的自我应用程序需要递归类型。
    • @NaCl 好吧,你可以,因为“fun”是“val rec”的派生形式,但它等同于使用“fun”。
    猜你喜欢
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多