How is arrow operator an Applicative Functor in Haskell?

Note: Still learning Haskell, not reached Monoids, studying Applicative Functors.

I saw this implementation and I am not entirely clear on it:

``````instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
``````

This is what I think:

Now I get what `(->) r a` is but I am not entirely clear on what it does. This is what I think it does:

• It takes two arguments (types) and returns a function from first to second type, i.e. `-> Int Int` returns `Int -> Int` which is of kind `*` but what about the definition?

Now `((->) r` is goind to be defined as an applicative functor that is a functor containing `r -> x`. So we have two cases:

• [`pure x = (\_ -> x)`]: For `pure` we need to wrap a given `-> r x` into some functor but we are defining a function that just ignores input data type and returns data type `x`. example `pure (*2)` should return `Maybe (Int -> Int)` or some other functor binding the given function `-> r x`
• [`f <*> g = \x -> f x (g x)`]: For two given functions whose first argument (data type) is same as `r` we wish to `<*>` or `fmap` one onto another, i.e. `(((->) r) f) <*> (((->) r) g)` or `(r->f) <*> (r->g)` but isn't `<*>` same as `(.)` for functions but for `(.)` they should be something like `a->b` and `b->c`? example `(*2) <*> (+7)` of the form `(Int -> Int) <*> (Int -> Int)`? (which comes out to be invalid but `(+) <\$> (*2) <*> (+7)` is valid?)

Note: for `(+) <\$> (*2) <*> (+7)` I think it is `((+) <\$> (*2)) <*> (+7)` which is `+ (*2 x) y` `fmap`-ed onto `(+7)` but how is this achieved?

What am I getting it wrong?

• `instance Applicative ((->) x) where pure v x = v ; (f <*> g) x = (f x) \$ (g x)` should be much clearer. – Will Ness Oct 28 '17 at 20:25
• "but isn't `<*>` [the] same as `(.)` for functions?" no, that's `<\$>`, so `(+) <\$> (*2) <*> (+7)` == `(\x -> (((+).(*2) x) \$ ((+7) x))`. – Will Ness Oct 29 '17 at 9:40

The type `(->) r a` is just an alias for `r -> a`, nothing more. Its kind is `*` (“type”).

The type constructor `(->) r` can be thought of as `r -> ___` where `r` is already known but `___` is to be filled in later. Its kind is `* -> *` (“type constructor”).

The `(->) r` type constructor is itself is parametrized by the input type `r`. To reduce the risk confusion, it might help to fix `r` to something concrete. So for the rest of this answer, I’ll choose `r = Int`. The explanation below will work for any choice of `r`.

Both applicative functors and functors classify type constructors, not types:

• We say a `[___]` (list constructor) is a functor, `Int -> ___` (functions that expect an integer) is a functor, `IO ___` is a functor, `Maybe ___` is a functor, etc.
• We do not say `[Int]` (list of integers) is a functor, nor do we say `Int -> String` (functions expect an integer and return a string) is a functor, nor `IO ()`, nor `Maybe String`, etc. (Of course, in informal writing people do say this out of sloppiness, but while learning it’s important to keep this distinction in mind.)

``````pure :: a ->        f a     -- general type, where f is Applicative
pure :: a -> (->) Int a     -- specialized type for f = ((->) Int)
pure :: a ->  (Int -> a)    -- just another way to write the above
pure x = (\_ -> x)
``````

The `pure` function creates a function that will return `a`, ignoring whatever `Int` it will receive. It provides a way to “wrap” things into an applicative functor.

As a concrete example, if you write `pure "hi"`, this creates a function `\_ -> "hi"` that always returns `"hi"` no matter what input it gets. To get your `"hi"` back, you apply the result to any integer, “unwrapping” the applicative functor:

``````>>> (pure "hi") 42
"hi"
``````

``````(<*>) ::        f (a -> b)  ->        f a  ->        f b     -- general type, where f is Applicative
(<*>) :: (->) Int (a -> b)  -> (->) Int a  -> (->) Int b     -- specialized type for f = ((->) Int)
(<*>) ::  (Int -> (a -> b)) ->  (Int -> a) ->  (Int -> b)    -- just another way to write the above
f <*> g = \x -> f x (g x)
``````

The `<*>` function takes two functions:

• The first function `f` will return a function `a -> b` in exchange for an `Int`.
• The second function `g` will return some value `a` in exchange for an `Int`.

The goal of `<*>` is to create a new function that produces some value `b` in exchange for an `Int`. There is one “obvious” way to play this game: when you do get that `Int` later in the future, you send it to both `f` and `g` and they will in exchange give you `a -> b` and `a`. Then you can apply the `a -> b` to `a` to get `b`, which achieves the goal.

Here’s a concrete example: `pure (+) <*> pure 2.0 <*> pure 3.0`. This expression creates a function that always yields `5.0` in exchange for whatever `Int` you give. As usual you can “unwrap” it by applying it to some `Int`:

``````>>> (pure (+) <*> pure 2.0 <*> pure 3.0) 42
5.0
``````

But so far, none of these examples were very interesting, because they only “wrap” things using `pure`, which always ignores the argument. Here’s a more interesting one:

``````>>> let get input = input
>>> (pure (-) <*> get <*> pure 7) 42
35
>>> (pure (-) <*> get <*> pure 7) 10
3
``````

Compared to the previous examples, the `get` function is rather unusual in that it does actually inspect the `Int` argument, returning exactly what it sees. This means the result of this chain of computations differs depending on what argument it receives at the very end.

``````  pure (-) <*> get <*> pure 7
≡ (\input -> (-)) <*> (\input -> input) <*> (\input -> 7)
≡ (\input -> (-) input) <*> (\input -> 7)
≡ (\input -> (-) input 7)
≡ (\input -> input - 7)
``````

In fact, if you just look at the original applicative expression and squint a bit to ignore the `pure` and `<*>`, you can read it directly as

``````  (-) INPUT 7
≡ INPUT - 7
``````

where `INPUT` represents the future `Int` value.

``````  (+) <\$> (*2) <*> (+7)
≡ (+) <\$> (\input -> input * 2) <*> (\input -> input + 7)
≡ (\input -> (+) (input * 2)) <*> (\input -> input + 7)
≡ (\input -> (+) (input * 2) (input + 7))
≡ (\input -> (input * 2) + (input + 7))
``````

Informally this describes the following computation:

``````  (+) (INPUT * 2) (INPUT + 7)
≡ (INPUT * 2) + (INPUT + 7)
``````

For example, if the input is 42, you should expect 133 as the result:

``````>>> ((+) <\$> (*2) <*> (+7)) 42
133
``````

The purpose of the `((->) Int)` applicative functor to allow the programmer to separate the logic that depends on the input argument from the actual code that supplies the concrete value. In other words, in real code you would likely be building a rather large and complicated applicative expression, without knowing what the input will be. You would not be unwrapping the applicative value right away, but likely some far-away place in the code (perhaps in another project entirely!).

Let's use some equational reasoning.

Our functor `f` is `(->) r`, so `f a` is `(->) r a` which is just `r -> a`.

`pure :: a -> f a`, so in this case `pure :: a -> (r -> a)`.

`<*> :: f (a -> b) -> f a -> f b`, so we get `<*> :: r -> (a -> b) -> (r -> a) -> (r -> b)`.

`fmap :: (a -> b) -> f a -> f b`, so we get `fmap :: (a -> b) -> (r -> a) -> (r -> b)`.

If you look at what `fmap` does, it takes a single-argument function and "puts it in" the functor. What about functions of two or more arguments? That's why we have applicative functors.

Say we have a function `g :: a -> b -> c -> d`. We want to apply it to arguments `x :: f a`, `y :: f b`, and `z :: f c`.

So we do `pure g <*> x <*> y <*> z`.

`pure g :: f (a -> b -> c -> d)`. Let's rewrite it as `f (a -> (b -> c -> d))`, since `<*>` expects an argument of type `f (a -> b)`.

`pure g <*> x :: f (b -> c -> d)`. We can rewrite it as `f (b -> (c -> d))` for clarity. You can see where this is going, and you end up with a result of type `f d`.

We can do the same thing for `fmap`, so `fmap f x` = `pure f <*> x`. Since we're going to start all these chains with the same thing, we can even abbreviate `fmap` as `<\$>`, so things look like `g <\$> x <*> y <*> z`.

but isn't `<*>` same as `(.)`

No, and you can tell by looking at the type signature. `(.) :: (b -> c) -> (a -> b) -> (a -> c)`, which does match our type signature for `fmap` above, except for shuffling around the letters.

`(*2) <*> (+7)`

This doesn't typecheck, as you noted. Why?

Let's say `f = (*2)` and `g = (+7)`, and both are of type `Int -> Int`.

`<*> :: (r -> (a -> b)) -> (r -> a) -> (r -> b)`.

But we know that `r = Int`, so `<*> :: (Int -> (a -> b)) -> (Int -> a) -> (Int -> b)`. Our second argument tells us that `a = Int`, which is fine, but our first argument is `Int -> Int` and doesn't have enough arguments.

I think it is `((+) <\$> (*2)) <*> (+7)` which is `+ (*2 x) y` fmap-ed onto `(+7)` but how is this achieved?

`((+) <\$> (*2)) <*> (+7)` means `\x -> (x*2) + (x+7)`. If you look at the definition of `<*>`, you see that `x` gets fed into both `f` and `g`.

One thing you are missing is that the "arrow operator" `(->)` works on types not values. (In other words it's a type constructor)

`(->) Int Int` is identical to `Int -> Int` which is a familiar function type you know and love. It is not a function; it's a function type.

Now `((->) r` is goind to be defined as an applicative functor that is a functor containing `r -> x`. So we have two cases:

I'm not sure what you mean by "containing" here. This is defining that `(->) r` aka `r ->` is a functor. It's not defining `r -> x` to be a functor. And a functor doesn't "contain" anything. (Well, `List` is functor that contains things, but other functors don't have to)

For `pure` we need to wrap a given `-> r x` into some functor

No. For `pure` we need to wrap a given `x` into a `-> r x` a.k.a. `r -> x` (which is a functor `-> r` applied to `x`).

but we are defining a function that just ignores input data type and returns data type x.

Indeed. That is how you convert an `x` into a `-> r x` a.k.a. `r -> x`.

example `pure (*2)` should return `Maybe (Int -> Int)`

It does - with the `Maybe` functor. `pure (*2) :: (Maybe (Int -> Int))` would do that - but it will not return `Maybe (Int -> Int)`, because that's a type; it will return `Just (*2)`.

`f <*> g = \x -> f x (g x)`: For two given functions whose first argument (data type) is same as r we wish to `<*>` or fmap one onto another, i.e. `(((->) r) f) <*> (((->) r) g)` or `(r->f) <*> (r->g)`

`(<*>)` is not the same as `fmap`. For this functor `fmap` is defined to be the same as `(.)`, and `(<*>)` isn't.

but isn't `<*>` same as `(.)` for functions

No.

but for `(.)` they should be something like `a->b` and `b->c`?

Right ... and for `(<*>)` they aren't like that, so clearly `(<*>)` is different from `(.)`

example `(*2) <*> (+7)` of the form `(Int -> Int) <*> (Int -> Int)`?

In the `(->) r` applicative functor, `<*>` can be thought of as "deferred application".

`(->) r` is similar to the `Reader r` monad - it represents computations that also have access to some "environment value". A "value" of type `a` that depends on the environment is represented as a `(->) r a` a.k.a. `r -> a` (cf. `Reader r a`). In other words, a `r -> a` is an "`a` wrapped in the functor `r ->`")

Now we can compare things to their equivalent forms "outside" the functor, to see how things work "inside".

Inside the functor, `(*2)` and `(+7)` are values (they're twice the environment value, and the environment value plus seven, respectively).

You can't apply a value to another value, so this doesn't work. (`(*2) <*> (+7)` is analogous to `4 9` for example)

(which comes out to be invalid but `(+) <\$> (*2) <*> (+7)` is valid?)

`(+) <\$> (*2) <*> (+7)` applies the function `(+)` to these values - yielding another "value wrapped in a functor" which will be three times the environment value plus seven. The result is equivalent to `\x -> (x*2) + (x+7)`.