看起来我对 Haskell 中的 Monoid 有很清楚的了解,但上次我听说了一种叫做自由幺半群的东西。

什么是自由幺半群?它与幺半群有什么关系?

你能在 Haskell 中提供一个例子吗?

最佳答案

在编程环境中,我通常将 free monoid 转换为 [a] 。在他关于 category theory for programmers 的优秀系列文章中,Bartosz Milewski 将 Haskell 中的 free monoids 描述为列表幺半群(假设忽略了无限列表的一些问题)。

标识元素为空列表,二元运算为列表拼接:

Prelude Data.Monoid> mempty :: [Int]
[]
Prelude Data.Monoid> [1..3] <> [7..10]
[1,2,3,7,8,9,10]

直觉上,我认为这个幺半群是“自由的”,因为它是一个你总是可以应用的幺半群,不管你想使用什么类型的值(就像自由 monad 是一个你总是可以从任何仿函数创建的 monad) .

此外,当一个类型存在多个幺半群时,自由幺半群会推迟决定使用哪个特定的幺半群。例如,对于整数,存在无限多个幺半群,但最常见的是加法和乘法。

如果您有两个(或更多整数),并且您知道您可能想要聚合它们,但您还没有决定要应用哪种类型的聚合,您可以改为使用免费的幺半群来“聚合”它们 - 实际上,这意味着将它们放在一个列表中:
Prelude Data.Monoid> [3,7]
[3,7]

如果您稍后决定要将它们添加在一起,那么这是可能的:
Prelude Data.Monoid> getSum $ mconcat $ Sum <$> [3,7]
10

相反,如果您希望将它们相乘,您也可以这样做:
Prelude Data.Monoid> getProduct $ mconcat $ Product <$> [3,7]
21

在这两个示例中,我特意选择将每个数字提升为一个类型( SumProduct ),它体现了一个更具体的幺半群,然后使用 mconcat 来执行聚合。

对于加法和乘法,有更简洁的方法可以做到这一点,但我这样做是为了说明如何使用更具体的幺半群来解释自由幺半群。

关于haskell - 自由幺半群和幺半群的主要区别是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54164346/

10-13 06:05