简体   繁体   中英

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 gxy = fyx is valid, then fyx = gxy 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 gxy = fyx 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

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  = g  where g x y = f y x

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

flip f x y =  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

flip takes a function and returns the flipped version of the function. One way to define flip' is to include the application in the definition itself, since

flip' f y x = f x y  ===> flip' f y = \x -> f x y
                     ===> flip' f = \y -> \x -> f x y

That is, flip' f is a function that applies f to its own arguments in reverse order.

The second definition simply gives the anonymous function \\y -> \\x -> fxy a name first, then uses that name as the definition of flip' fxy .

                     ===> flip' f = g where g = \y -> \x -> f x y
                     ===> flip' f = g where g y = \x -> f x y
                     ===> flip' f = g where g y x = f x y

That is, flip' f is some function g , where g is defined to apply f to the arguments of g in reverse order.

The definitions gxy = fyx and gyx = fxy are equivalent up to alpha conversion . In both cases, f is a free variable in the definition of g ; g is as a closure over the f argument to flip' .

If you are here looking for what flip does:

Prelude> pow x y = x ^ y
Prelude> pow 2 3
8
Prelude> flip pow 2 3
9

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM