【问题标题】:YCombinator not working in SwiftYCombinator 在 Swift 中不工作
【发布时间】:2023-03-14 03:09:01
【问题描述】:

我正在尝试创建一个 lambda 函数来获取阶乘函数,但这会引发分段错误和错误。我如何让这个在 Swift 中工作。请观看此视频以了解我正在尝试做的事情http://www.confreaks.com/videos/1287-rubyconf2012-y-not-adventures-in-functional-programming

typealias f = () -> ()
typealias g = (Int) -> (Int)
typealias F = Any -> g

let y = { (gen: Any) -> g in
    (gen as F)(gen)
}
let fact = y({ (gen: Any) -> g in
    { (n: Int) -> Int in
        if n == 0 {
            return 1
        } else {
            return n * (gen as F)(gen)(n - 1)
        }
    }
})

fact(10)

【问题讨论】:

  • 它现在可以在最新的测试版中运行。

标签: swift y-combinator


【解决方案1】:

great post by xiliangchen 介绍了如何在 Swift 中创建 Y-combinator。 (从技术上讲,这不是 Y-组合器,因为它是显式递归的,但它在很大程度上可以满足您的需求。)这是 Y 函数的一个示例(为了清楚起见,去掉了它的通用规范) :

typealias G = Int -> Int

func Y (f: G -> G) -> G {
    return {
        (i: Int) -> Int in
        f(Y(f))(i)
    }
}

let factorial = Y { (f: G) -> G in
    { (n: Int) -> Int in
        if n == 0 {
            return 1
        } else {
            return n * f(n - 1)
        }
    }
}

factorial(5)        // 120

有关 Y-combinators 的更多信息,您可以查看此terrific (long) piece by Mike Vanier。

(注意:使用Any 有点混乱——我建议尽可能避免使用它,尤其是因为在这种情况下你不需要它。)

【讨论】:

  • 你能把它更新到现代的 Swift 4.1 吗?这可能听起来很傻,但我真的不知道如何让它编译
【解决方案2】:

您可以使用递归类型实现真正的(没有显式递归的)Y 组合器,没有任何不安全的技巧(感谢 Rosetta Code):

struct RecursiveFunc<F> {
  let o : RecursiveFunc<F> -> F
}

func Y<A, B>(f: (A -> B) -> A -> B) -> A -> B {
  let r = RecursiveFunc<A -> B> { w in f { w.o(w)($0) } }
  return r.o(r)
}

let factorial = Y { (f: Int -> Int) -> Int -> Int in
  { $0 <= 1 ? 1 : $0 * f($0-1) }
}
println(factorial(10))

Any 并没有真正的帮助,因为Any cannot represent function types。

更新:从 Xcode 6.1 beta 3 开始,Any 可以表示函数类型,并且您的代码可以正确编译和工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多