How to write a flip method in Swift?

2019-08-03 17:20发布

I want to write a flip method in Swift.

Here is the signature. Prelude> :t flip flip :: (a -> b -> c) -> b -> a -> c

My code in 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)
        }
    }
}

The flip1 method can not compile. There is an error Extra argument in call at line return f(valueA, valueB)

The flip2 method works fine, except the flipped method can only be called like this method(1)(2).

How to write the flip method so that I can use the flipped method like method(1, 2) and method(1)(2)?

标签: swift
1条回答
倾城 Initia
2楼-- · 2019-08-03 18:24

A->B->C is the type of a function taking one argument of type A and returning a function B->C (a "curried" function). The type of a function taking two arguments is (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

It can slightly be shortened to

func flip<A, B, C>(f: (A, B)->C) -> (B, A)->C {

    return { (valueB, valueA) in
        f(valueA, valueB)
    }
}

due to automatic type inference.

As far as I know, Swift does not automatically convert functions taking multiple arguments into curried functions, compare Typecase regular Swift function to Curry Function.

查看更多
登录 后发表回答