2014-09-26 54 views
2

我想创建一个lambda函数来得到一个阶乘函数,但是这会引发一个分段错误和错误。我如何在Swift中使用这个工作。请看看这个视频以供参考什么,我试图做http://www.confreaks.com/videos/1287-rubyconf2012-y-not-adventures-in-functional-programmingYCombinator不能在Swift中工作

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) 
+0

它现在可以在最新的测试版中使用。 – newacct 2014-09-30 02:18:39

回答

0

有一个great post by xiliangchen通过创造斯威夫特的Y组合子散步。 (从技术上讲,这不是一个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型组合器的更多信息,可以看看这个terrific (long) piece by Mike Vanier

注:使用Any是那种乱七八糟的 - 我建议你敬而远之吧,只要你能,特别是因为你不需要它在这种情况下)。

1

您可以实现一个真正的(没有明确的递归)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可以代表函数类型,你的代码编译和工作正常。