哈斯克尔:如何加入自然转型?

use*_*370 19 monads haskell category-theory

我可以在Haskell中定义一个自然变换:

h :: [a] -> Maybe a
h []    = Nothing
h (x:_) = Just x
Run Code Online (Sandbox Code Playgroud)

并且具有函数k:

k :: Char -> Int
k = ord
Run Code Online (Sandbox Code Playgroud)

由于以下事实,满足了自然条件:

h . fmap k == fmap k . h

可以join用类似的方式证明List monad 函数的自然条件吗?我有一些麻烦了解如何join,说concat特别,是一个自然的转变.

C. *_*ann 16

好的,我们来看看吧concat.

首先,这是实施:

concat :: [[a]] -> [a]
concat = foldr (++) []
Run Code Online (Sandbox Code Playgroud)

这与你h所在的地方的结构相似Maybe,[]并且更重要的[]是被 - 取代 - 暂时滥用语法 - [[]].

[[]]当然,它也是一个仿函数,但它不是Functor自然条件使用它的实例.直接翻译您的示例将不起作用:

concat . fmap k =/= fmap k . concat

...因为两者fmap都只在最外层工作[].

虽然[[]]假设Functor你是一个有效的实例,但由于实际原因,这可能是显而易见的.

但是,您可以重建正确的提升,如下所示:

concat . (fmap . fmap) k == fmap k . concat

...其中fmap . fmap相当于fmap假设Functor实例的实现[[]].

作为一个相关的附录,return出于相反的原因很尴尬:a -> f a是一个从省略的身份探险家的自然转变.使用: []身份将如下编写:

(:[]) . ($) k == fmap k . (:[])

......完全多余($)的东西代表fmap着被遗忘的身份探险者.