Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the flip function work?

Tags:

haskell

Haskell newbie here. I was going through Learn you a haskell, and came across this definition of the flip function.

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

What I don't get is, where did x and y come from? I mean, the signature tells me that flip' is a function that takes a function (with two parameters), and returns a function (again, with two parameters).

If I'm understanding this right, when I write a function which goes like

foo :: (a -> b) -> a -> b
foo f x = f x   -- applies the function f on x

But then, in this case I'm passing the parameter explicitly [ ie x ] and so I'm able to access it in the function body. So how come the flip' function can access the parameters x and y?

like image 579
ersran9 Avatar asked Jan 18 '13 10:01

ersran9


People also ask

What does flip function do in Haskell?

Flip simply takes a function and returns a function that is like our original function, only the first two arguments are flipped. We can implement it like so: flip' :: (a -> b -> c) -> (b -> a -> c)

What does the operator do in Haskell?

Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).

How do you use until in Haskell?

until condition and while condition do ... statements. while stops when the condition is false, until stops when the condition is true. In the same language, two different conventions.


5 Answers

The Prelude, which is in the base package at hackage.haskell.org, is included with an implicit import in every Haskell file is where the flip function is found. On the right side you can click "source" and see the source code for flip.

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

The where clause allows for local definitions, x=10 or y="bla". You can also define functions locally with the same syntax you would for the top level. add x y = x + y

In the below equivalent formulation I make the substitution g = f y x

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

Right now g takes no parameters. But what if we defined g as g a b = f b a well then we would have:

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

No we can do a little algebraic cancelation(if you think of it like algebra from math class you will be pretty safe). Focusing in on:

flip f x y   =  g x y

Cancel the y on each side for:

flip f x   =  g x

Now cancel the x:

flip f   =  g

and now to put it back in the full expression:

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

As a last cosmetic step we can make the substitution a to x and b to y to recover the function down to argument names:

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

As you can see this definition of flip is a little round about and what we start with in the prelude is simple and is the definition I prefer. Hope that helps explain how where works and how to do a little algebraic manipulation of Haskell code.

like image 167
Davorak Avatar answered Oct 17 '22 22:10

Davorak


flip' doesn't access x and y. It receives an argument f, and evaluates to the expression g. No x or y in sight.

However, g is itself a function, defined with an auxiliary equation in the where clause of flip'.

You can read g x y = f y x exactly as if it were a top level equation like flip'. So g is a function of two arguments, x and y. It's g that has access to x and y, not flip'. Values for those arguments don't exist until g is applied, which is not until after flip' has returned the function g (if ever).

The thing that's special that about g being defined in the where clause of flip' is that it can have access to the arguments of flip', which is how g can be defined in terms of f.

So when flip' is invoked it receives a function f. For each particular invocation of flip', it constructs a new function g. g would receive two arguments, x and y, when it is called, but that hasn't happened yet. flip' then just returns g as its result.

like image 17
Ben Avatar answered Oct 17 '22 22:10

Ben


One simple example to understand and illustrate, on your ghci do:

Prelude> sub x y = x - y
Prelude> sub 3 1
2
Prelude> flip sub 3 1
-2
like image 2
Henry H. Avatar answered Oct 18 '22 00:10

Henry H.


Let's find the type of g.

We know flip type : (a -> b -> c) -> (b -> a -> c)

Therefore we can deduce f type : (a -> b -> c)

We have this definition for g

g x y = f y x

From the right-hand-side we deduce that y :: a and x :: b.

Hence g :: b -> a -> c

Note that the definition could be rewritten without the 'where' clause.

flip' f = g where g x y = f y x
-> flip' f a b = g a b where g a b = f b a
-> flip' f a b = f b a
like image 1
Paul R Avatar answered Oct 18 '22 00:10

Paul R


Put simply, you can also define functions in a where block. So the variables x and y are just the formal parameters of g, and that's why you can access it in g x y = f y x: g x y defines formal parameters x and y, and f y x is the definition of what g does. Finally, that definition is returned from flip f = g.

like image 1
evzh Avatar answered Oct 17 '22 23:10

evzh