Reputation: 1877
We have signatures:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Let us play with it a bit:
(/) <$> Just 5 <*> Just 2
=> Just 2.5
((/) <$> Just 5 ) <*> Just 2
=> Just 2.5
( Just (\x -> 5/x ) ) <*> Just 2
=> Just 2.5
Question:
((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^ @@@@@@
(<$>) :: Functor f => (a -> b) -> f a -> f b
^^^
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
^^^^^^^^^^ @@@
I interpret that ^^^ parts should match by their type. How come return type of <$>
doesn't visually match input type of <*>
in signatures?
What do I miss here? Thanks.
Upvotes: 3
Views: 190
Reputation: 477608
It does match, but the f
, a
and b
of the (<$>)
and (<*>)
function are variables, and the variables are different variables each time you use that function.
It therefore makes more sense to define the functions here as:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
So that means that the ^
and @
indeed match like:
((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^ @@@@@@
(<$>) :: Functor f => (a -> b) -> f a -> f b
^^^
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
^^^^^^^^^^ @@@
So we know that the type of (/) <$> Just 5
is f b
, and g (c -> d)
, whereas Just 2
has type g c
. Since Just 2
has type Just 2 :: Num n => Maybe n
, that thus means that g ~ Maybe
and c ~ n
(here x ~ y
means x
and y
are the same type). Furthermore we can derive that f b ~ g (c -> d)
, so f ~ Maybe
, and b ~ (c -> d)
.
We can furthermore analyze the (/) <$> Just 5
expression. We know that Just 5
has type Num m => Maybe m
, so that means that a ~ m
. The function (/)
has type (/) :: Fractional k => k -> k -> k
, so that means that a ~ b ~ k ~ m
, and therefore we know that (/) <$> Just 5
has type (/) <$> Just 5 :: (Num m, Fractional m) => Maybe (m -> m)
, or less verbose (/) <$> Just 5 :: Fractional m => Maybe (m -> m)
(a Fractional m
implies Num m
).
As we already found out b ~ (c -> d)
, so that means that m ~ c ~ d
, and thus the type of the expression is: ((/) <$> Just 5) <*> Just 2 :: Fractional m => Maybe m
.
Upvotes: 6