Haskell 哈斯克尔:加入是一种自然的转变吗?
我可以在Haskell中将自然转换定义为:Haskell 哈斯克尔:加入是一种自然的转变吗?,haskell,monads,category-theory,Haskell,Monads,Category Theory,我可以在Haskell中将自然转换定义为: h :: [a] -> Maybe a h [] = Nothing h (x:_) = Just x 并使用函数k: k :: Char -> Int k = ord 符合自然条件是因为: h。fmap k=fmap k。h List monad的join函数的自然条件是否可以用类似的方式演示?我在理解join,尤其是concat是如何自然转换时遇到了一些困难。好的,让我们看看concat 首先,这里是实现: concat ::
h :: [a] -> Maybe a
h [] = Nothing
h (x:_) = Just x
并使用函数k:
k :: Char -> Int
k = ord
符合自然条件是因为:
h。fmap k
=fmap k。h
List monad的
join
函数的自然条件是否可以用类似的方式演示?我在理解join
,尤其是concat
是如何自然转换时遇到了一些困难。好的,让我们看看concat
首先,这里是实现:
concat :: [[a]] -> [a]
concat = foldr (++) []
这与h
的结构类似,其中可能被[]
取代,更重要的是,[]
被--to滥用语法--[[]]
取代
当然,[[]]
也是一个函子,但它不是自然主义条件使用它的方式的函子
实例。直接翻译您的示例不起作用:
concat。fmap k
=/=fmap k。concat
…因为两个fmap
仅在最外层的[]
上工作
尽管假定[[]]
是Functor
的一个有效实例,但由于可能显而易见的实际原因,您不能直接将其作为一个实例
但是,您可以重建正确的提升,如下所示:
concat。(fmap.fmap)k
=fmap k。concat
…其中fmap。fmap
相当于对[[]
的假设函子
实例实现fmap
作为一个相关的附录,return
由于相反的原因而显得笨拙:a->fa
是一个省略的身份函子的自然转换。使用:[]
可以将标识写为:
(:[])。($)k
=fmap k。(:[])
…在这里,完全多余的($)
代替了elided identity函子的fmap
。回答得很好,谢谢。我开始理解return
的原因是Haskell可能会要求我们使用i7
或I[1,2,3]
等来构造每个值。但这种方法可能有自己的缺点。@user643722:通常很笨拙。否则它是完全等价的,ia
和a
之间的转换是微不足道的。使用显式标识函子的等效方法是对嵌套列表使用newtype
,例如newtype L2 a=L2[[a]]
,并将其作为函子的实例。请记住,函子
类型类只能描述非常有限的有效函子子集,也就是说,从所有Hask到它的一个子类的函子是由一个单一类型的构造函数定义的*->*
。是否值得使用Compose
fromtransformers
?这确实让我们为[[]]
编写了fmap
的有效定义,如果您将[[[]]]
编写为Compose[][]
@ocharles:当然,创建一个包装器来描述函子的组成一直是可能的。这与直接表示函子合成并不完全相同。如果我写(f.g)
并将其应用于x
,我不必以某种方式打开结果以获得与f(gx)
相同的值。令人惊讶的是,由于Reynolds参数,任何看起来像fa->ga
的合理多态Haskell函数都是一种自然变换(对底部的常见问题进行模化)。这意味着您实际上不必检查每个单独的函数,看看它是否满足自然变换的条件。它们是“自由定理”。开始阅读的地方是: