trying to understand how is the final signature inferred:
GHCi> :t (+)
(+) :: Num a => a -> a -> a
GHCi> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
GHCi> :t (<*>) (+)
(<*>) (+) :: Num b => (b -> b) -> b -> b
(a' -> a' -> a')
has to be unified with f (a -> b)
, so f
is probably of type ((->) r)
:
(<*>) :: Applicative ((->) r) => r -> (a -> b) -> (r -> a) -> (r -> b)
(<*>) (+) ~ a' -> (a' -> a') -> (a' -> a') -> (a' -> a')
(<*>) (+) :: (a' -> a') -> (a' -> a') -- ^^^ got stuck here
Can anybody explain how to get the final type ?
Thanks.
The problem you are having is with the right associativity of ->
. Consider the type of <*>
:
<*> :: (Applicative f) => f (a -> b) -> f a -> f b
With f a
equal to r -> a
, we have
<*> :: f (a -> b) -> f a -> f b
:: (r -> (a -> b)) -> (r -> a) -> (r -> b)
:: (r -> a -> b) -> (r -> a) -> (r -> b) -- This is the key line
Notice that it went from (r -> (a -> b)) -> other stuff
to (r -> a -> b) -> other stuff
, not r -> (a -> b) -> other stuff
. We can remove the inner parentheses because they are on the right of an arrow, but we cannot remove the outer parentheses, as they are on the left of an arrow.
Now, (+) :: (Num a) => a -> a -> a
. This fits perfectly with the first argument of <*>
when r
is the same as a
is the same as b
and they all are numbers. All together, we get that
(<*>) (+) :: (Num a) => (a -> a) -> (a -> a)
:: (Num a) => (a -> a) -> a -> a
Note again that I am removing parentheses on the right, but not on the left of the arrow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With