如何在Swift中编写翻转方法?

时间:2015-06-02 10:48:55

标签: swift

我想在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)这样的翻转方法?

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)
    }
}