Reputation: 6130
I have the applicative <$>
operator more or less figured out, but I can't understand the signature I'm getting with the following example:
ghci> let f x y z = x + y + z -- f::Num a => a -> a -> a -> a
ghci> f <$> Just 2 <*> Just 3 <*> Just 4
Just 9
This result I understand, but when checking the following type:
ghci> :t (<$> f)
(<$> f) :: Num a => ((a -> a -> a) -> b) -> a -> b --This makes no sense to me
That signature I would understand as : a function that takes a (a -> a- > a) -> b
function and an a
as parameters and returns a b
. According to this reasoning , I should call this like :
(<$>f) f 4
which would result in an Integer
.
Obviously this is not true, so can you please help me understand how to read the type of (<$> f)
?
Upvotes: 1
Views: 123
Reputation: 116174
<$>
takes as a second argument something of type g b
, where g
is any applicative functor.
You are passing f :: Num a => a -> a -> a -> a
as a second argument. Let's ignore the Num a
context to keep things simple.
Hence, we look for g,b
such that g b = a -> a -> a -> a
.
Let's write the type of f
in prefix form:
f :: (->) a ((->) a ((->) a a)) = g b
Hence, g = (->) a
and b = ((->) a ((->) a a))
. The latter is b = a -> a -> a
in infix form.
It happens that (->) a
is an applicative functor, so <$> f
type checks. Note however that <$>
is used on a completely different functor than the Maybe
one you were using in your examples. Hence the confusion.
TL;DR: overloaded identifiers can shapeshift to many things adapting to their contexts, possibly in some unexpected way.
Upvotes: 1
Reputation: 370425
a function that takes a
(a -> a- > a) -> b
function and ana
as parameters and returns ab
.
This is correct.
According to this reasoning , I should call this like :
(<$>f) f 4
which would result in an
Integer
.
No, because f
does not have type (a -> a -> a) -> b
or one compatible with it. Instead it has type Num a => a -> a -> a -> a
. That is, f
takes three numbers and produces a number, whereas we're looking for a function that takes a function (of type a -> a -> a
) as its first argument.
Upvotes: 3