最近我正在通过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]
类型? 最佳答案
如果您意识到自己是 fmap
,这很容易理解。 -ing over 是一个函数,而不是 Maybe a
值(value)。 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]
但由于添加了
.
,这完全不同。 .
关于haskell - 为什么 "fmap (replicate 3) Just"的类型为 "a -> [Maybe a]",在 Haskell 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24006068/