我正在阅读有关应用仿函数的LYAH chapter,我似乎不理解以下示例:
ghci> :t fmap (++) (Just "hey")
fmap (++) (Just "hey") :: Maybe ([Char] -> [Char])
但是当我看到这个时:
ghci> :t (++)
(++) :: [a] -> [a] -> [a]
ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
我确实理解(* 3)或(++“this”)之类的内容如何适合(a - > b)类型,但我只是看不出 [a] - > [a] - > [a] 符合(a - > b)?
答案 0 :(得分:7)
关键是->
与右侧相关联,因此像a -> b -> c
这样的类型确实是a -> (b -> c)
。因此,设置[a] -> [a] -> [a]
〜c -> d
和c
〜[a]
,d
符合[a] -> [a]
。您可以将函数[a] -> [a] -> [a]
视为返回类型[a]
的结果的2个参数的函数,或者返回类型为[a] -> [a]
的结果的1参数的函数。
答案 1 :(得分:6)
要意识到的是b
中的a -> b
不必是标量 - 它可以是一个函数。
[a] -> [a] -> [a]
可以被视为[a] -> ([a] -> [a])
,因此b
是[a] -> [a]
答案 2 :(得分:5)
像往常一样把东西放在一边,
fmap :: Functor f => ( a -> b ) -> f a -> f b
fmap (++) (Just "hey") :: f b
(++) :: [c] -> ([c] -> [c])
所以,
a ~ [c] , b ~ ([c] -> [c]) , f ~ Maybe , a ~ [Char] , c ~ Char
f b ~ Maybe b ~ Maybe ([c] -> [c]) ~ Maybe ([Char] -> [Char])
这里不涉及任何想法。类型的统一是一个机械过程。
要回答您的具体问题(转述),“[c] -> [c] -> [c]
如何与a -> b
”匹配,请点击此处:
答案 3 :(得分:4)
真的很简单:-)。让我添加一个简单的括号:
[a]->[a]->[a]
与[a]->([a]->[a])
因此,a->b
将[a]
和b替换为[a]->[a]
,从而适合string->string
。你给一个字符串给++,你得到一个类型为fmap (++) (Just "hey")
的函数作为回报
Maybe ([Char] -> [Char])
是一个monad,它可以保存一个函数,该函数将字符串“hey”作为前缀添加到另一个字符串。它确实属于{{1}}
答案 4 :(得分:4)
考虑Maybe类型的fmap定义。
fmap f (Just x) = Just (f x)
您的示例看起来像
fmap (++) (Just "Hey") = Just ("Hey" ++) :: Maybe ([Char] -> [Char])
正如fmap应该的那样,你只需在Maybe容器中解除(++)函数 将其应用于内容。