Haskell: join 是如何自然转变的?

发布于 2024-11-06 03:58:35 字数 366 浏览 8 评论 0原文

我可以在 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)是如何自然转换的。

I can define a natural transformation in Haskell as:

h :: [a] -> Maybe a
h []    = Nothing
h (x:_) = Just x

and with a function k:

k :: Char -> Int
k = ord

the naturality condition is met due to the fact that:

h . fmap k == fmap k . h

Can the naturality condition of the List monad's join function be demonstrated in a similar way? I'm having some trouble understanding how join, say concat in particular, is a natural transformation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野却迷人 2024-11-13 03:58:35

好的,让我们看看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 相当于为 [[]] 假设的 Functor 实例实现 fmap

作为相关附录,return 由于相反的原因而显得尴尬:a ->; f a 是来自省略恒等函子的自然变换。使用 : [] 身份将被写成:

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

...其中完全多余的 ($) 代替了省略的恒等函子上的 fmap

Okay, let's look at concat.

First, here's the implementation:

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

This parallels the structure of your h where Maybe is replaced by [] and, more significantly, [] is replaced by--to abuse syntax for a moment--[[]].

[[]] is a functor as well, of course, but it's not a Functor instance in the way that the naturality condition uses it. Translating your example directly won't work:

concat . fmap k =/= fmap k . concat

...because both fmaps are working on only the outermost [].

And although [[]] is hypothetically a valid instance of Functor you can't make it one directly, for practical reasons that are probably obvious.

However, you can reconstruct the correct lifting as so:

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

...where fmap . fmap is equivalent to the implementation of fmap for a hypothetical Functor instance for [[]].

As a related addendum, return is awkward for the opposite reason: a -> f a is a natural transformation from an elided identity functor. Using : [] the identity would be written as so:

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

...where the completely superfluous ($) is standing in for what would be fmap over the elided identity functor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文