Search code examples
haskellfunctional-programminghigher-order-functions

Definition of the flip function in Haskell


Currently I am trying to learn Haskell with the book 'Learn You a Haskell' and I'm trying to understand the implementations of the flip function in chapter 5. The problem is that the author states that if g x y = f y x is valid, then f y x = g x y must be also true. But how and why does this reversal affects the two function definitions?

I know how currying works and I also know that the -> operator is right-associative by default so the type declarations are in fact the same. I also understand the functions apart from each other but not how the reversal of g x y = f y x is in relation with this.

first flip function

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

second flip function

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

Solution

  • I think the argument the author has in his head got wildly abbreviated to the point that it's not even sensical. But here is my guess about the reasoning. We start with the first definition:

    flip f = g where g x y = f y x
    

    Now we observe that this is a curried thing, and we use all the discussion of associativity of (->) and junk to write the same thing, but with two extra arguments to f. Like this:

    flip f x y = g x y where g x y = f y x

    Now we have the equation that he called out as going both ways: g x y = f y x and vice versa. We can rewrite the body of the flip using this equation, like this:

    flip f x y = f y x where g x y = f y x

    Since the body of the definition no longer mentions g, we can delete it.

    flip f x y = f y x
    

    And now we're pretty much there. In the final definition, the author has swapped the names x and y everywhere. I don't know why they chose to do so, but it is a legal move that you can make in equational reasoning, so no problem there. Doing so gives us their final equation:

    flip f y x = f x y