2014-09-26 87 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可以代表函數類型,你的代碼編譯和工作正常。