sablib
sablib

Reputation: 23

How to write a flip method in Swift?

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

Upvotes: 3

Views: 275

Answers (2)

Blazej SLEBODA
Blazej SLEBODA

Reputation: 9925

This is the @MartinR answer updated to Swift 5.1

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

It can slightly be shortened to

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

    { (valueB: B, valueA: A) in
        f(valueA, valueB)
    }
}

Upvotes: 0

Martin R
Martin R

Reputation: 539805

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.

Upvotes: 2

Related Questions