Andriy Drozdyuk
Andriy Drozdyuk

Reputation: 61121

How to partially apply the flip function?

I am a little confused about what the "partial" application of flip might do.

Since the type of the flip function is:

flip :: (a -> b -> c) -> b -> a -> c

which we can write without the parenthesis as:

flip :: a -> b -> c -> b -> a -> c

How can I partially apply it to only the first argument a? To get a function with the type:

flipa ::     b -> c -> b -> a -> c

Or it doesn't make sense?

For example if I have something like:

let foo a b = (Just a, b)
:t foo
> foo:: a -> t -> (Maybe a, t)

It makes sense to partially apply it:

let a = foo 1
:t a
a :: t -> (Maybe Integer, t)

Upvotes: 3

Views: 579

Answers (3)

Matt Fenwick
Matt Fenwick

Reputation: 49105

As others have noted, the type (a -> b -> c) -> b -> a -> c is not the same as a -> b -> c -> b -> a -> c.

However, it is the same as (a -> b -> c) -> (b -> a -> c).

That shows that flip is a function that takes a single argument as input and therefore can't be partially applied*.


*: from the point of view of that flip returns a function of type b -> a -> c, which is not the only valid point of view in Haskell.

Upvotes: 3

Chris Taylor
Chris Taylor

Reputation: 47402

It doesn't make sense. The signature

f :: a -> b -> c

is equivalent to

f :: a -> (b -> c)

and not equivalent to

f :: (a -> b) -> c

This convention is why you can partially apply function in Haskell in the first place. Since all functions are curried by default, the signature f :: a -> b -> c can be interpreted as

f takes a and b, and returns c

or can equally validly be interpreted as

f takes a, and returns a function that takes b and returns c

Upvotes: 19

Matthew Walton
Matthew Walton

Reputation: 9969

(a -> b -> c) -> b -> a -> c is not the same as a -> b -> c -> b -> a -> c because the -> operator is right-associative, not left-associative. Therefore, partially applying flip is meaningless because it only has one parameter in the first place.

Also, your example doesn't make much sense because it would still produce an output function taking an a, which you would presumably not want. But if you take that out, you get a function which takes a unary function and produces exactly the same unary function, so just partially apply the original function and you're done.

Upvotes: 7

Related Questions