Given a Haskell function func :: a -> b -> c, we can produce a function flippedFunc :: b -> a -> c easily using flip from Prelude.

flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x

One of my favorite ways to explain flip uses the fact that because the function arrow (->) associates to the right, we can rewrite the type signature as:

(a -> b -> c) -> (b -> a -> c)

This indicates a transformation from one function into another function, with the order of the first two arguments reversed.

However, what if we want an arbitrary reordering of function arguments? There’s actually a straightforward (if messy) recipe to produce reorderings using just flip and composition (.), but it requires understanding a few rules.

First, flip by itself only swaps the first two arguments. Doing two flips in a row flip (flip f) is idempotent, meaning a double flip has no effect on f’s behavior.

For the following examples, let’s use this three-argument function f and four-argument function g:

f :: a -> b -> c -> d
g :: a -> b -> c -> d -> e

We know that flip f swaps the first two arguments:

flip f
:: b -> a -> c -> d

Two flips in a row does nothing.

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

That do-nothing example can also be written as a chain of function composition:

flip . flip . f
:: a -> b -> c -> d

If we want to swap arguments other than the first two, we need to compose. For example, to swap the second and third argument, we use flip . f

flip . f
:: a -> c -> b -> d

However, we’ve already seen that flip . flip . f takes us back to doing nothing. If we wanted to swap the third and fourth arguments of some four-argument function g, we’d need to nest compositions.

(flip .) . g
:: a -> b -> d -> c -> e

Here’s a listing of how we can generate all the possible argument order permutations of f:

f
:: a -> b -> c -> d

flip . f
:: a -> c -> b -> d

flip f
:: b -> a -> c -> d

flip . flip f
:: b -> c -> a -> d

flip . flip (flip . flip f)
:: c -> a -> b -> d

flip (flip . flip f)
:: c -> b -> a -> d

We can use these flipped functions to do certain things, like partial application of arbitrary arguments.

thirdArgApplied :: a -> b -> d
thirdArgApplied = flip . flip (flip . flip f) $c where c = someDefaultArgument Say we had a massive 25-argument function: alphabet :: a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> n -> o -> p -> q -> r -> s -> t -> u -> v -> w -> x -> y -> z We can swap arbitrary pairs of arguments. Here’s how to flip x and y in alphabet: ((((((((((((((((((((((flip .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) .) . alphabet Of course, what this all means is that we can do arbitrary manipulations of argument orderings, no matter how convoluted. Here’s an example where I’ve additionally used $ (instead of just parentheses, flip, and .) for…um…readability:

((((((((((((((((flip.).).).).).).).).).).).).).).).)$((((((( ((((((((((flip.).).).).).).).).).).).).).).).).)$(((((((((((
(((((((flip.).).).).).).).).).).).).).).).).).)$(((((((((((( (((((((flip.).).).).).).).).).).).).).).).).).).)$((((((((((
((((((((((flip.).).).).).).).).).).).).).).).).).).).)$((((( ((((((((((((((((flip.).).).).).).).).).).).).).).).).).).).) .)$((((((((((((((((((((((flip.).).).).).).).).).).).).).).).
).).).).).).)$(((((((((((((((((((((((flip.).).).).).).).).). ).).).).).).).).).).).).).)$(((((((((((((((flip.).).).).).).
).).).).).).).).)$((((((((((((((((flip.).).).).).).).).).).) .).).).).)$(((((((((((((((((flip.).).).).).).).).).).).).).)
.).).)$((((((((((((((((((flip.).).).).).).).).).).).).).).). ).).)$(((((((((((((((((((flip.).).).).).).).).).).).).).).).
).).).)$((((((((((((((flip.).).).).).).).).).).).).).)$(((((
((((((((flip.).).).).).).).).).).).).)$((((((((((((((flip.). ).).).).).).).).).).).).)$(((((((((((((((flip.).).).).).).).
).).).).).).).)$((((((((((((((((flip.).).).).).).).).).).).) .).).).)$(((((((((((((((((flip.).).).).).).).).).).).).).).)
.).)$((((((((((((((((((flip.).).).).).).).).).).).).).).).). ).)$(((((((((((((((((((flip.).).).).).).).).).).).).).).).).
).).)$((((((((((((((((((((flip.).).).).).).).).).).).).).).) .).).).).)$(((((((((((((((((((((flip.).).).).).).).).).).).)
.).).).).).).).).)$((((((((((((((((((((((flip.).).).).).).). ).).).).).).).).).).).).).).)$(((((((((((((((((((((((flip.).
).).).).).).).).).).).).).).).).).).).).).)$((((((((((((flip .).).).).).).).).).).).)$(((((((((((((flip.).).).).).).).).)
.).).).)$((((((((((((((flip.).).).).).).).).).).).).).)$((((
(((((((((((flip.).).).).).).).).).).).).).).)$(((((((((((((( ((flip.).).).).).).).).).).).).).).).)$(((((((((((((((((flip
.).).).).).).).).).).).).).).).).)$(((((((((((flip.).).).).) .).).).).).)$((((((((((((flip.).).).).).).).).).).).)$(((((( (((((((flip.).).).).).).).).).).).).)$((((((((((((((flip.).)
.).).).).).).).).).).).)$(((((((((((((((flip.).).).).).).).) .).).).).).).)$((((((((((((((((flip.).).).).).).).).).).).).
).).).)$(((((((((((((((((flip.).).).).).).).).).).).).).).). ).)$((((((((((((((((((flip.).).).).).).).).).).).).).).).).)
.)$(((((((((((((((((((flip.).).).).).).).).).).).).).).).).) .).)$((((((((((((((((((((flip.).).).).).).).).).).).).).).).
).).).).)$(((((((((((((((((((((flip.).).).).).).).).).).).). ).).).).).).).).)$(((((((((flip.).).).).).).).).)$(((((((((( flip.).).).).).).).).).)$(((((((((((flip.).).).).).).).).).)
.)$((((((((((((flip.).).).).).).).).).).).)$(((((((((((((
flip.).).).).).).).).).).).).)$((((((((((((((flip.).).).).) .).).).).).).).).)$(((((((((((((((flip.).).).).).).).).).).)
.).).).)$((((((((((((((((flip.).).).).).).).).).).).).).).). )$(((((((((((((((((flip.).).).).).).).).).).).).).).).).)$(( ((((((((((((((((flip.).).).).).).).).).).).).).).).).).)$(((
(((((flip.).).).).).).).)$(((((((flip.).).).).).).)$((((((((
flip.).).).).).).).)$(((((((((flip.).).).).).).).).)$(((((((
(((flip.).).).).).).).).).)$(((((((((((flip.).).).).).).).). ).).)$((((((((((((flip.).).).).).).).).).).).)$((((((flip.). ).).).).)$(((((((flip.).).).).).).)$(((((flip.).).).).)$((((
((flip.).).).).).)$(((((((flip.).).).).).).)$((((((((flip.).
).).).).).).)$(((((((((flip.).).).).).).).).)$((((((((((flip
.).).).).).).).).).)$((((flip.).).).)$(((((flip.).).).).)$(( ((((flip.).).).).).)$(((((((flip.).).).).).).)$((((((((flip. ).).).).).).).)$(((((((((flip.).).).).).).).).)$(((((((((( flip.).).).).).).).).).)$(((((((((((flip.).).).).).).).).).)
.)$((((((((((((flip.).).).).).).).).).).).)$(((((((((((((
flip.).).).).).).).).).).).).)$((((((((((((((flip.).).).).). ).).).).).).).).)$(((((((((((((((flip.).).).).).).).).).).).
).).).)$((((((((((((((((flip.).).).).).).).).).).).).).).).)$(((((((((((((((((flip.).).).).).).).).).).).).).).).).)$((( (((((((((((((((flip.).).).).).).).).).).).).).).).).).)$((((
(((((((((((((((flip.).).).).).).).).).).).).).).).).).).)$(( (flip.).).)$((((flip.).).).)$(((((flip.).).).).)$((((((flip.
).).).).).)$(((((((flip.).).).).).).)$((((((((flip.).).).).)
.).).)$(((((((((flip.).).).).).).).).)$((((((((((flip.).).).
).).).).).).)$(((((((((((flip.).).).).).).).).).).)$((((((((
((((flip.).).).).).).).).).).).)$(((((((((((((flip.).).).).) .).).).).).).).)$((((((((((((((flip.).).).).).).).).).).).).
).)$(((((((((((((((flip.).).).).).).).).).).).).).).)$((((((
((((((((((flip.).).).).).).).).).).).).).).).)$((flip.).)$((
(flip.).).)$((((flip.).).).)$(((((flip.).).).).)$(flip.)$((
flip.).)$(((flip.).).)$((((flip.).).).)$(((((flip.).).).).)$
((((((flip.).).).).).)$(((((((flip.).).).).).).)$flip$(flip. )$((flip.).)$(((flip.).).)$((((flip.).).).)$(((((flip.).).). ).)$((((((flip.).).).).).)$(((((((flip.).).).).).).)$(((((((
(flip.).).).).).).).)$(((((((((flip.).).).).).).).).)$((((((
((((flip.).).).).).).).).).)$(((((((((((flip.).).).).).).).) .).).)$((((((((((((flip.).).).).).).).).).).).)$(((((((((((( (flip.).).).).).).).).).).).).)$((((((((((((((flip.).).).).)
.).).).).).).).).)$(((((((((((((((flip.).).).).).).).).).).) .).).).)$((((((((((((((((flip.).).).).).).).).).).).).).).).
)$(((((((((((((((((flip.).).).).).).).).).).).).).).).).)$((
((((((((((((((((flip.).).).).).).).).).).).).).).).).).)
alphabet

This is a (thoroughly) flipped-around version of alphabet, with the type signature:

:: t -> h -> e ->
q -> u -> i -> c -> k ->
b -> r -> a -> w -> n -> y ->
f -> o -> x ->
d -> g -> j -> l -> m -> p -> s -> v -> z