Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applicative functors: why can fmap take a function with more than one argument?

I am getting into Haskell and found the book "learn you a Haskell" most helpful. I am up to the section on applicative functors.

I am puzzled by the following as it appears in the book:

(\x y z -> [x, y, z]) <$> (+3) <*> (*2) <*> (/2) $ 5

which yields the output:

[8.0,10.0,2.5]

First of all, I have confirmed my suspicion in ghci in regards to precedence of the operators, so that the above equals the following ugly statement:

(((\x y z -> [x,y,z]) <$> (+3)) <*> (*2) <*> (/2)) $ 5 

So from that it becomes clear that the first thing that happens is the fmap call via the (<$>) infix operator.

And this is the core of what boggles my mind currently. The definition of fmap (here shown as infix (<$>)) is:

(<$>) :: (Functor f) => (a -> b) -> f a -> f b

But in the equation I am struggling with, (\x y z -> [x, y, z]) takes three arguments, not just one. So how could the first argument of type (a -> b) be satisfied?

I think it might have to do with partial application / currying but I cannot figure it out. I would greatly appreciate an explanation. Hope I have formulated the question well enough.

like image 357
Felix Schlitter Avatar asked Jan 27 '14 08:01

Felix Schlitter


People also ask

Are all monads applicative functors?

Every Monad is an Applicative Just as IO , every monad can be made into an applicative functor.

Is Fmap a functor?

The expression fmap (*2) is a function that takes a functor f over numbers and returns a functor over numbers. That functor can be a list, a Maybe , an Either String, whatever. The expression fmap (replicate 3) will take a functor over any type and return a functor over a list of elements of that type.

What does Fmap do Haskell?

fmap is used to apply a function of type (a -> b) to a value of type f a , where f is a functor, to produce a value of type f b . Note that for any type constructor with more than one parameter (e.g., Either ), only the last type parameter can be modified with fmap (e.g., b in `Either a b`).

Is applicative a functor?

Applicative functors are the programming equivalent of lax monoidal functors with tensorial strength in category theory. Applicative functors were introduced in 2008 by Conor McBride and Ross Paterson in their paper Applicative programming with effects.


1 Answers

Simple answer: there are no functions with multiple arguments in Haskell!

There are two candidates for what you might call "dyadic function": a function that takes a (single!) tuple, and – by far prevalent in Haskell – curried functions. Those take just one argument, but the result is a function again.

So, to figure out what e.g. fmap (+) does, let's write

type IntF = Int -> Int

-- (+) :: Int -> IntF
-- fmap :: ( a -> b  ) ->  f a -> f b
--  e.g.:: (Int->IntF) -> f Int->f IntF

Test it yourself in GHCi:

Prelude> type IntF = Int -> Int
Prelude> let (#) = (+) :: Int -> IntF
Prelude> :t fmap (#)
fmap (#) :: Functor f => f Int -> f IntF

like image 50
leftaroundabout Avatar answered Oct 08 '22 03:10

leftaroundabout