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

applicative, functor, haskell

Solution

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

Problem

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.

Original source