I'm reading the LYAH chapter on applicative functors, and I don't seem to understand the following example:
ghci> :t fmap (++) (Just "hey")
fmap (++) (Just "hey") :: Maybe ([Char] -> [Char])
But when I look at this:
ghci> :t (++)
(++) :: [a] -> [a] -> [a]
ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
I do understand how something like (*3) or (++"this") fits into the (a -> b) type, but I just can't see how [a] -> [a] -> [a] fits into (a -> b) ?
The key is that ->
associates to the right, so a type like a -> b -> c
is really a -> (b -> c)
. So [a] -> [a] -> [a]
fits into c -> d
by setting c
~ [a]
and d
~ [a] -> [a]
. You can view a function [a] -> [a] -> [a]
either as a function of 2 arguments that returns a result of type [a]
, or a function of 1 argument that returns a result of type [a] -> [a]
.
The thing to realise is that the b
in a -> b
doesn't have to be a scalar - it can be a function.
[a] -> [a] -> [a]
can be thought of as [a] -> ([a] -> [a])
, so b
is [a] -> [a]
Putting the stuff side-by-side as usual,
fmap :: Functor f => ( a -> b ) -> f a -> f b
fmap (++) (Just "hey") :: f b
(++) :: [c] -> ([c] -> [c])
So,
a ~ [c] , b ~ ([c] -> [c]) , f ~ Maybe , a ~ [Char] , c ~ Char
f b ~ Maybe b ~ Maybe ([c] -> [c]) ~ Maybe ([Char] -> [Char])
No thinking is involved here. Unification of types is a mechanical process.
And to answer your specific question (paraphrased), " how [c] -> [c] -> [c]
can be matched with a -> b
" , here goes:
It is simple really :-). let me add a simple parenthesis:
[a]->[a]->[a]
is like [a]->([a]->[a])
So it fits in a->b
by replacing a by [a]
and b by [a]->[a]
. You give a string to ++ and you get a function of type string->string
in return
fmap (++) (Just "hey")
is a maybe monad holding a function which prefix the string "hey" to another string. It is indeed of type Maybe ([Char] -> [Char])
Consider the definition of fmap for the Maybe type.
fmap f (Just x) = Just (f x)
which for your example looks like
fmap (++) (Just "Hey") = Just ("Hey" ++) :: Maybe ([Char] -> [Char])
As fmap should, you have simply lifted the (++) function inside the Maybe container and applied it to the contents.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.