如果您意识到fmap-ing 是一个函数,而不是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-ing 结束的是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]
但由于添加了.,这完全不同。