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

时间:2011-05-08 23:09:16

标签: 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是一种自然转换。

1 个答案:

答案 0 :(得分:16)

好的,让我们看一下concat

首先,这是实施:

concat :: [[a]] -> [a]
concat = foldr (++) []

这与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对于被省略的身份仿函数。