Search code examples
haskellfunctorapplicative

(r ->) applicative functor


I am having some trouble understanding how the function instance (->) r of Applicative works in Haskell.

For example if I have

(+) <$> (+3) <*> (*100) $ 5

I know you get the result 508, I sort of understand that you take the result of (5 + 3) and (5 * 100) and you apply the (+) function to both of these.

However I do not quite understand what is going on. I assume that the expression is parenthesized as follows:

((+) <$> (+3)) <*> (*100)

From my understanding what is happening is that your mapping (+) over the eventual result of (+3) and then you are using the <*> operator to apply that function to the eventual result of (*100)

However I do not understand the implementation of <*> for the (->) r instance and why I cannot write:

(+3) <*> (*100)

How does the <*>, <$> operator work when it comes to (->) r?


Solution

  • <$> is just another name for fmap and its definition for (->) r is (.) (the composition operator):

    intance Functor ((->) r) where
      fmap f g = f . g
    

    You can basically work out the implementation for <*> just by looking at the types:

    instance Applicative ((->) r) where
      (<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
      f <*> g = \x -> f x (g x)
    

    You have a function from r to a to b and a function from r to a. You want a funtion from r to b as a result. First thing you know is you return a function:

    \x ->
    

    Now you want to apply f since it is the only item which may return a b:

    \x -> f _ _
    

    Now the arguments for f are of type r and a. r is simply x (since it alrady is of type r and you can get an a by applying g to x:

    \x -> f x (g x)
    

    Aaand you're done. Here's a link to the implementation in Haskell's Prelude.