2014-09-26 2 views
2

계승 함수를 얻기 위해 람다 함수를 만들려고하는데 이것으로 인해 분할 오류가 발생하고 오류가 발생합니다. 스위프트에서 어떻게 작동합니까? 내가 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

답변

0

을하려고하고 무엇에 참조 할 수 있도록이 비디오를보고 스위프트의 Y-콤비를 만드는 과정 산책 great post by xiliangchen있다하십시오.

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- 콤비 아니지만, 크게 당신이 원하는 것을) 여기에 Y 기능의 예 (선명도에 대한 일반적인 사양을 박탈)

Y-combinators에 대한 자세한 내용은 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 때문에 도움이되지 않습니다.

업데이트 : 엑스 코드 6.1 베타 3부터, Any 기능 유형을 나타낼 수 있고, 당신의 코드를 컴파일하고 올바르게 작동합니다.

관련 문제