最近我正在使用Learn You a Haskell for Great Good在线学习Haskell。
我有两个问题:
fmap (replicate 3)
的类型为Functor f=> f a -> f [a]
。为什么可以将其应用于Just
?
此外,为什么fmap (replicate 3) Just
类型a -> [Maybe a]
而不是a -> Maybe [a]
类型?
答案 0 :(得分:13)
如果您意识到fmap
结束的是功能而不是Maybe a
值,这很容易理解。 Just
的类型为a -> Maybe a
,因此它属于(->) a
仿函数,而不是Maybe
仿函数。函数Functor
的实例看起来像
instance Functor ((->) a) where
fmap g f = g . f
所以fmap
只是成为正常的功能组合!这意味着
fmap (replicate 3) Just
与
相同replicate 3 . Just
非常清楚地具有类型a -> [Maybe a]
更多"类型代数"解释是排列类型和替代,直到你不能再。让我们从我们的类型开始,但使用不同的变量名称,以便更容易理解:
fmap :: Functor f => (a -> b) -> (f a -> f b)
replicate :: Int -> c -> [c]
Just :: x -> Maybe x
然后是fmap (replicate 3)
:
(replicate 3) :: c -> [c]
fmap :: (a -> b) -> (f a -> f b)
所以
(c -> [c]) ~ (a -> b)
暗示
c ~ a
[c] ~ b
b ~ [a]
所以替换回来:
fmap (replicate 3) :: f c -> f [c]
那么我们fmap
的结果是Just
,其类型为
Just :: x -> Maybe x
可以在前缀格式中重写为
Just :: (->) x (Maybe x)
或者如果我们真的想要更多括号
Just :: ((->) x) (Maybe x)
然后
Just :: ((->) x) (Maybe x)
fmap (replicate 3) :: f c -> f [c]
暗示
((->) x) (Maybe x) ~ f c
(->) x ~ f
Maybe x ~ c
[c] ~ [Maybe x]
所以替换回来:
fmap (replicate 3) :: ((->) x) (Maybe x) -> ((->) x) [Maybe x]
回到中缀符号
fmap (replicate 3) :: (x -> Maybe x) -> (x -> [Maybe x])
然后应用Just
:
fmap (replicate 3) Just :: x -> [Maybe x]
我想在此强调,Maybe
为Functor
与此减少无关,唯一涉及的Functor
是函数Functor
。列表也是Functor
,但仅仅因为它出现在replicate
类型中并不意味着在这种情况下它很重要。很容易与函数混淆
fmap (replicate 3) . Just :: a -> Maybe [a]
但由于添加了.
,这完全不同。
答案 1 :(得分:4)
Functor
正在使用的fmap
实例是(->) r
,而不是Maybe
。让我们来看看类型:
replicate 3 :: a -> [a]
fmap (replicate 3) :: Functor f => f a -> f [a]
Just :: b -> Maybe b
fmap (replicate 3) Just
中,我们需要将Functor f => f a
部分与b -> Maybe b
匹配。这选择的实例是(->) r
实例(因为Just
是一个函数),我们最终得到((->) r a) -> ((->) r [a])
。(->)
应用程序以获取此类型(专门将函数作为其参数):(r -> a) -> (r -> [a])
。Just
的类型,我们需要将r
与b
和a
与Maybe b
匹配(以便我们可以将(r -> a)
与(b -> Maybe b)
匹配)给我们(b -> Maybe b) -> (b -> [Maybe b])
。fmap (replicate 3)
的专用类型,我们现在可以将Just
应用于fmap (replicate 3) Just :: b -> [Maybe b]
,与a -> [Maybe a]
相同。作为旁注,fmap
实例专用的完整类型(->) r
为fmap :: (a -> b) -> (r -> a) -> (r -> b)
,这意味着它与函数组合相同:fmap = (.)
。