我想在Swift中编写一个翻转方法。
这是签名。
Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c
我在Swift中的代码:
func flip1<A, B, C>(f: A->B->C) -> (B->A->C) {
return { (valueB: B, valueA: A) in
return f(valueA, valueB)
}
}
func flip2<A, B, C>(f: A->B->C) -> (B->A->C) {
return { (valueB: B) in
return { (valueA: A) in
return f(valueA)(valueB)
}
}
}
flip1
方法无法编译。第Extra argument in call
行
return f(valueA, valueB)
flip2
方法工作正常,但翻转方法只能像method(1)(2)
一样调用。
如何编写flip
方法,以便我可以使用method(1, 2)
和method(1)(2)
这样的翻转方法?
答案 0 :(得分:1)
A->B->C
是一个带有A
类型参数的函数的类型
并返回一个函数B->C
(一个&#34; curried&#34;函数)。功能的类型
两个参数是(A, B)->C
:
func flip<A, B, C>(f: (A, B)->C) -> (B, A)->C {
return { (valueB: B, valueA: A) in
return f(valueA, valueB)
}
}
let x = flip(-)(10, 5)
println(x) // -5
可略微缩短为
func flip<A, B, C>(f: (A, B)->C) -> (B, A)->C {
return { (valueB, valueA) in
f(valueA, valueB)
}
}
由于自动类型推断。
据我所知,Swift不会自动转换功能 将多个参数纳入curried函数,进行比较 Typecase regular Swift function to Curry Function
答案 1 :(得分:0)
这是已更新为Swift 5.1的@MartinR答案
func flip<A, B, C>(_ f: @escaping (A, B)->C) -> (B, A)->C {
return { (valueB: B, valueA: A) in
return f(valueA, valueB)
}
}
let x = flip(-)(10,5)println(x)// -5
可以略微缩短为
func flip<A, B, C>(_ f: @escaping (A, B)->C) -> (B, A)->C {
{ (valueB: B, valueA: A) in
f(valueA, valueB)
}
}