2016-01-06 88 views
1

我正在閱讀此blog。當我在我自己的方法試着寫咖喱功能:swift中的咖喱函數語法


func stdCurry(f : (A,B) -> C) -> (A)->(B->C) { 
    return { (a:A) ->(B -> C) in { 
      (b:B) -> C in 
      { 
       return f(a,b) 
      } 

     } 

    } 
} 

我得到了一個錯誤:

:7:22: error: declared closure result 'C' is incompatible with contextual type '_' (b:B) -> C in ^ _

但是當我刪除尾隨周圍封閉的花括號那麼它不會報告任何錯誤。任何人都可以幫助我理解這一點。

+1

這是因爲,你試圖通過這些外來的花括號後推出又一塊「(b:b - >下,在」其實你在這種情況下,只想要2封嵌套,如果你介紹那些如花括號,最終得到3個閉包而不是2. – Shripada

回答

2

內部花括號-> in { ... }告訴swift,這個內部部分是一個閉包,而它實際上只包含一個值(C類型評估f(a,b))。如果你刪除這些內部大括號,你的例子工作。

例如,嘗試

func stdCurry<A,B,C>(f : (A,B) -> C) -> (A) -> (B -> C) { 
    return { (a:A) -> (B -> C) in { 
     (b:B) -> C in 
     return f(a,b) // <-- this is not a closure (just returns a value of type C` 
     } 
    } 
} 

請注意,我已經添加了泛型類型上面的函數簽名(也許你函數是一個類的一部分,你會得到你的類型A,從那裏BC) 。

爲了使上述更清晰的錯誤,認爲這是一個有點簡單的例子(採取關閉並返回它):

/* This is ok */ 
func myClosure<A,B>(f: (A) -> B) -> (A) -> B { 
    return { 
    x in f(x) 
    } 
} 

/* Error: return type here is not (A) -> B, but contains 
    an anonymous closure() -> B */ 
func myClosure<A,B>(f: (A) -> B) -> (A) -> B { 
    return { 
     x in { f (x) } 
    } 
} 

/* Ok */ 
func myClosure<A,B>(f: (A) -> B) -> (A) -> (() -> B) { 
    return { 
     x in { f(x) } 
    } 
} 

還要注意,由於斯威夫特知道(推斷)---從你的函數簽名---類型以及每個in ...陳述的期望回報類型,可以省略關閉類型((a:A) -> (B -> C))以及return關鍵字,並使您的表達更加緊湊,如下所示:

func stdCurry<A, B, C>(f: (A, B) -> C) -> A -> (B -> C) { 
    return { a in { b in f(a, b) } } 
} 

在下面的評論你的要求:你可以利用「多條語句」尾部例如通過使用該方法的第三個「簡單的例子」的上面,如:

func stdCurry<A,B,C>(f : (A,B) -> C) -> (A) -> (B) ->() -> C { 
    return { (a:A) -> (B ->() -> C) in { 
     (b:B) ->() -> C in 
     return { 
      // ... 
      f(a,b) 
     } 
     } 
    } 
} 

注意,作爲函數簽名的增長多少有些「雜亂」,這是有利的在你的函數,即實際關閉忽略這些細節:

func stdCurry<A,B,C>(f : (A,B) -> C) -> (A) -> (B) ->() -> C { 
    return { a in { 
     b in 
     return { 
      // ... 
      f(a,b) 
     } 
     } 
    } 
} 
+0

謝謝,還有一個查詢。如果在尾部有多個語句,我該怎麼辦? – Raviprakash

+0

@Ravi prakash樂於幫助。你可以在返回類型('() - > B')中使用匿名閉包,請參閱上面我編輯的第三個「簡單示例」。 – dfri