2016-01-06 63 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