Guo*_*eng 7 haskell types functor
最近我正在网上学习Haskell,学习Haskell for Great Good.
我有两个问题:
fmap (replicate 3)
是类型的Functor f=> f a -> f [a]
.为什么可以应用它Just
?
此外,为什么是fmap (replicate 3) Just
类型a -> [Maybe a]
,而不是类型a -> Maybe [a]
?
bhe*_*ilr 13
如果你意识到你所处的fmap
是一个功能而不是一个Maybe a
价值,这很容易理解.类型Just
是a -> Maybe a
,所以它属于(->) a
仿函数,而不是Maybe
仿函数.Functor
函数的实例看起来像
instance Functor ((->) a) where
fmap g f = g . f
Run Code Online (Sandbox Code Playgroud)
所以fmap
只是成为正常的功能组合!这意味着
fmap (replicate 3) Just
Run Code Online (Sandbox Code Playgroud)
是相同的
replicate 3 . Just
Run Code Online (Sandbox Code Playgroud)
这显然有类型 a -> [Maybe a]
一个更"类型代数"的解释是排列类型并替换直到你不能再进行.让我们从我们的类型开始,但使用不同的变量名称,以便更容易遵循:
fmap :: Functor f => (a -> b) -> (f a -> f b)
replicate :: Int -> c -> [c]
Just :: x -> Maybe x
Run Code Online (Sandbox Code Playgroud)
然后fmap (replicate 3)
:
(replicate 3) :: c -> [c]
fmap :: (a -> b) -> (f a -> f b)
Run Code Online (Sandbox Code Playgroud)
所以
(c -> [c]) ~ (a -> b)
Run Code Online (Sandbox Code Playgroud)
这暗示着
c ~ a
[c] ~ b
b ~ [a]
Run Code Online (Sandbox Code Playgroud)
所以代替:
fmap (replicate 3) :: f c -> f [c]
Run Code Online (Sandbox Code Playgroud)
那么我们正在经历的fmap
是Just
哪种类型
Just :: x -> Maybe x
Run Code Online (Sandbox Code Playgroud)
哪个可以用前缀形式重写为
Just :: (->) x (Maybe x)
Run Code Online (Sandbox Code Playgroud)
或者如果我们真的想要更多括号
Just :: ((->) x) (Maybe x)
Run Code Online (Sandbox Code Playgroud)
然后
Just :: ((->) x) (Maybe x)
fmap (replicate 3) :: f c -> f [c]
Run Code Online (Sandbox Code Playgroud)
这暗示着
((->) x) (Maybe x) ~ f c
(->) x ~ f
Maybe x ~ c
[c] ~ [Maybe x]
Run Code Online (Sandbox Code Playgroud)
所以代替:
fmap (replicate 3) :: ((->) x) (Maybe x) -> ((->) x) [Maybe x]
Run Code Online (Sandbox Code Playgroud)
并回到中缀符号
fmap (replicate 3) :: (x -> Maybe x) -> (x -> [Maybe x])
Run Code Online (Sandbox Code Playgroud)
然后申请Just
:
fmap (replicate 3) Just :: x -> [Maybe x]
Run Code Online (Sandbox Code Playgroud)
我想在这里强调,那Maybe
是一个Functor
没有任何与本次减持,唯一Functor
涉及的是功能Functor
.列表也是一个Functor
,但仅仅因为它出现在类型中replicate
并不意味着它在这种情况下很重要.很容易与功能混淆
fmap (replicate 3) . Just :: a -> Maybe [a]
Run Code Online (Sandbox Code Playgroud)
但由于增加了,这完全不同.
.