Cartesian product not working for applicative

I was trying to understand applicative and how i can use it as a cartesian product between `K` functions and `N` parameters ,and i can't comprehend why i can't do the following:

`[Just (+1),Just (+2)] <*> [Just 1 ,Just 2]` renders

Error

``````* Couldn't match expected type `Maybe Integer -> b'
with actual type `Maybe (Integer -> Integer)'
* Possible cause: `Just' is applied to too many arguments      In the expression: Just (+ 1)      In the first argument of `(<*>)', namely `[Just (+ 1), Just (+ 2)]'
In the expression: [Just (+ 1), Just (+ 2)] <*> [Just 1, Just 2]
``````

I do not understand since from the definition it is supposed to take the functions out of the context, take the values and apply all combinations.

I have also tried :

`:t [pure (+1),pure (+2)] <*> [Just 1 ,Just 2] :: Num a => [a -> a]` and i can't understand why the resulting type is not a list of values (and not `a->a`) ,since all operators expect only one argument,and i am already supplying that.

Can someone shed some light?

• The context (in this case `[]`) does not contain functions. It contains `Maybe`s. So trying to apply the functions in the context is a type error. This is why the error says that it expected a function but actually got a `Maybe` instead. Try `[(+1), (+2)] <*> [1,2]` instead. – Rein Henrichs Apr 20 at 21:02
• You here have two levels of functors: a list, and a `Maybe`. – Willem Van Onsem Apr 20 at 21:04
• Are you deliberately trying to compose the two applicatives `[]` and `Maybe`? If so, then this won't work by default because GHC doesn't understand you're working with a composition. You need to make a new type for the composition, either with Compose or "by hand" with something like `newtype MaybeList a = [Maybe a]` (and then supply your own `Applicative` instance for `MaybeList`). – Robin Zigmond Apr 20 at 21:15

There are two applicative layers involved here (`[]` and `Maybe`), so `(<*>)` itself must be applied applicatively:

``````GHCi> (<*>) <\$> [Just (+1),Just (+2)] <*> [Just 1 ,Just 2]
[Just 2,Just 3,Just 3,Just 4]
``````

This use case is captured by the `Compose` newtype. Nesting any two applicative functors gives rise to another applicative:

``````GHCi> import Data.Functor.Compose
GHCi> Compose [Just (+1),Just (+2)] <*> Compose [Just 1 ,Just 2]
Compose [Just 2,Just 3,Just 3,Just 4]
``````

.

• Can you elaborate how does `<\$>` work in this case? You have a `f g (k::a->a)` and `f g a` .So you have two functors `f` and `g`. You have an `a` and a `a->a`.I do not understand how you unwrap the functors using `(<*>) <\$>` in the first case. – Bercovici Adrian Apr 21 at 6:03
• @BercoviciAdrian In this example, the first list is `[Maybe (Integer -> Integer)]`. `(<\$>)` maps through the list layer (but not the `Maybe` one). We have `(<*>) :: Applicative f => f (a -> b) -> (f a -> f b)`, so the first `(<*>)` specialises to `Maybe (Integer -> Integer) -> (Maybe Integer -> Maybe Integer)` -- we're (partially) applying `(<*>)` to the `Maybe`values in the first list. That being so, `(<*>) <\$> [Just (+1),Just (+2)]` ends up being `[Maybe Integer -> Maybe Integer]`, which is what you need to use with the second `(<*>)` (which, like the `(<\$>)`, uses the list `Applicative`). – duplode Apr 21 at 6:46
• But i do not understand then why you can't unwrap without using the `<\$>`.I mean `(<*>) [Just (+1)]` would mean you bind the first argument , and then you can just supply the value one. Your generic argument becomes `a`=`Maybe a` – Bercovici Adrian Apr 21 at 6:59
• @BercoviciAdrian For that to work, `Just (+1)` would have to be a function, but it isn't one (it is a `Maybe`-value that holds a function). `(<*>)` can only work through one applicative layer; that's why we need a second `(<*>)`. (The alternative is using `Compose` to handle the two layers as one.) – duplode Apr 21 at 7:05