简体   繁体   English

自由幺半群和幺半群的主要区别是什么?

[英]What is the main difference between Free Monoid and Monoid?

Looks like I have a pretty clear understanding what a Monoid is in Haskell, but last time I heard about something called a free monoid.看起来我对 Haskell 中的Monoid有很清楚的了解,但上次我听说了一种叫做自由幺半群的东西。

What is a free monoid and how does it relate to a monoid?什么是自由幺半群?它与幺半群有什么关系?

Can you provide an example in Haskell?你能在 Haskell 中提供一个例子吗?

In a programming context, I usually translate free monoid to [a] .在编程环境中,我通常将free monoid翻译为[a] In his excellent series of articles about category theory for programmers , Bartosz Milewski describes free monoids in Haskell as the list monoid (assuming one ignores some problems with infinite lists).在 Bartosz Milewski 为程序员撰写的关于范畴论的优秀系列文章中,Bartosz Milewski 将 Haskell 中的自由幺半群描述为列表幺半群(假设忽略了无限列表的一些问题)。

The identity element is the empty list, and the binary operation is list concatenation:标识元素为空列表,二元运算为列表拼接:

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

Intuitively, I think of this monoid to be 'free' because it a monoid that you can always apply, regardless of the type of value you want to work with (just like the free monad is a monad you can always create from any functor).直觉上,我认为这个幺半群是“自由的”,因为它是一个你总是可以应用的幺半群,不管你想使用什么类型的值(就像自由 monad 是一个你总是可以从任何函子创建的 monad) .

Additionally, when more than one monoid exists for a type, the free monoid defers the decision on which specific monoid to use.此外,当一个类型存在多个幺半群时,自由幺半群会推迟决定使用哪个特定的幺半群。 For example, for integers, infinitely many monoids exist, but the most common are addition and multiplication.例如,对于整数,存在无限多个幺半群,但最常见的是加法和乘法。

If you have two (or more integers), and you know that you may want to aggregate them, but you haven't yet decided which type of aggregation you want to apply, you can instead 'aggregate' them using the free monoid - practically, this means putting them in a list:如果您有两个(或更多整数),并且您知道您可能想要聚合它们,但您还没有决定要应用哪种类型的聚合,您可以改为使用免费的幺半群来“聚合”它们 - 实际上,这意味着将它们放在一个列表中:

Prelude Data.Monoid> [3,7]
[3,7]

If you later decide that you want to add them together, then that's possible:如果您稍后决定要将它们添加在一起,那么这是可能的:

Prelude Data.Monoid> getSum $ mconcat $ Sum <$> [3,7]
10

If, instead, you wish to multiply them, you can do that as well:相反,如果您希望将它们相乘,您也可以这样做:

Prelude Data.Monoid> getProduct $ mconcat $ Product <$> [3,7]
21

In these two examples, I've deliberately chosen to elevate each number to a type ( Sum , Product ) that embodies a more specific monoid, and then use mconcat to perform the aggregation.在这两个示例中,我特意选择将每个数字提升为包含更具体幺半群的类型( SumProduct ),然后使用mconcat执行聚合。

For addition and multiplication, there are more succinct ways to do this, but I did it that way to illustrate how you can use a more specific monoid to interpret the free monoid.对于加法和乘法,有更简洁的方法可以做到这一点,但我这样做是为了说明如何使用更具体的幺半群来解释自由幺半群。

As you already know, a monoid is a set with an element e and an operation <> satisfying正如你已经知道的,幺半群是一个包含元素e和操作<>满足的集合

e <> x = x <> e = x  (identity)
(x<>y)<>z = x<>(y<>z)  (associativity)

Now, a free monoid, intuitively, is a monoid which satisfies only those equations above, and, obviously, all their consequences.现在,一个自由幺半群,直观地,是一个只满足上述方程的幺半群,显然,满足它们的所有结果。

For instance, the Haskell list monoid ([a], [], (++)) is free.例如,Haskell 列表幺半群([a], [], (++))是免费的。

By contrast, the Haskell sum monoid (Sum Int, Sum 0, \\(Sum x) (Sum y) -> Sum (x+y)) is not free, since it also satisfies additional equations.相比之下,Haskell sum monoid (Sum Int, Sum 0, \\(Sum x) (Sum y) -> Sum (x+y))不是免费的,因为它也满足附加方程。 For instance, it's commutative例如,它是可交换的

x<>y = y<>x

and this does not follow from the first two equations.这不是从前两个方程得出的。

Note that it can be proved, in maths, that all the free monoids are isomorphic to the list monoid [a] .请注意,可以证明,在数学中,所有自由幺半群与列表幺半群[a]同构。 So, "free monoid" in programming is only a fancy term for any data structure which 1) can be converted to a list, and back, with no loss of information, and 2) vice versa, a list can be converted to it, and back, with no loss of information.因此,编程中的“自由幺半群”只是任何数据结构的花哨术语,它 1) 可以转换为列表,然后返回,不会丢失信息,2) 反之亦然,列表可以转换为列表,并返回,不会丢失信息。

In Haskell, you can mentally substitute "free monoid" with "list-like type".在 Haskell 中,你可以用“类列表类型”替代“自由幺半群”。

A free monoid is a specific type of monoid.自由幺半群是一种特定类型的幺半群。 Specifically, it's the monoid you get by taking some fixed set of elements as characters and then forming all possible strings from those elements.具体来说,它是通过将一些固定的元素集作为字符然后从这些元素形成所有可能的字符串而获得的幺半群。 Those strings, with the underlying operation being string concatenation, form a monoid, and that monoid is called the free monoid.这些字符串的底层操作是字符串连接,形成一个幺半群,这个幺半群称为自由幺半群。

A monoid (M,•,1) is a mathematical structure such that:幺半群(M,•,1)是一个数学结构,使得:

  1. M is a set M是一个集合
  2. 1 is a member of M 1M的成员
  3. • : M * M -> M
  4. a•1 = a = 1•a
  5. Given elements a , b and c in M , we have a•(b•c) = (a•b)•c .给定M元素abc ,我们有a•(b•c) = (a•b)•c

A free monoid on a set M is a monoid (M',•,0) and function e : M -> M' such that, for any monoid (N,*,1) , given a (set) map f : M -> N we can extend this to a monoid morphism f' : (M',•,0) -> (N,*,1) , ie集合M上的自由幺半群是幺半群(M',•,0)和函数e : M -> M'使得对于任何幺半群(N,*,1) ,给定一个(集合)映射f : M -> N我们可以将其扩展为幺半群态射f' : (M',•,0) -> (N,*,1) ,即

f a = f' (e a)
f' 0 = 1
f' (a•b) = (f' a) • (f' b)

In other words, it is a monoid that does nothing special.换句话说,它是一个没有任何特殊作用的幺半群。

An example monoid is the integers with the operation being addition and the identity being 0. Another monoid is sequences of integers with the operation being concatenation and the identity being the empty sequence.一个幺半群的例子是运算为加法且单位为 0 的整数。另一个幺半群是整数序列,运算为串联,单位为空序列。 Now the integers under addition is not a free monoid on the integers.现在加法下的整数不是整数上的自由幺半群。 Consider the map into sequences of integers taking n to (n) .考虑映射到整数序列的n(n) Then for this to be free we would need to extend this to a map taking n + m to (n,m) , ie it must take 0 to (0) and to (0,0) and to (0,0,0) and so on.然后为了让它免费,我们需要将它扩展到一个将n + m带到(n,m)的映射,即它必须从0(0)和到(0,0)(0,0,0)等。

On the other hand if we try to look at sequences of integers as a free monoid on the integers, we see that it seems to work in this case.另一方面,如果我们尝试将整数序列视为整数上的自由幺半群,我们会发现它似乎在这种情况下有效。 The extension of the map into the integers with addition is one that takes the sum of a sequence (with the sum of () being 0).将映射扩展为带加法的整数是取序列之和(() 之和为 0)。

So what is the free monoid on a set S ?那么集合S上的自由幺半群是什么? Well one thing we could try is just arbitrary binary trees of S .我们可以尝试的一件事就是S任意二叉树。 In a Haskell type this would look like:在 Haskell 类型中,这看起来像:

data T a = Unit | Single a | Conc (T a) (T a)

And it would have an identity of Unit , e = Single and (•) = Conc .并且它的标识为Unite = Single(•) = Conc

And we can write a function to show how it is free:我们可以编写一个函数来显示它是如何免费的:

-- here the second argument represents a monoid structure on b
free :: (a -> b) -> (b -> b -> b, b) -> T a -> b
free f ((*),zero) = f' where
  f' (Single a) = f a
  f' Unit = zero
  f' (Conc a b) = f' a * f' b

It should be quite obvious that this satisfies the required laws for a free monoid on a .它应该是相当明显的,这满足需要在自由幺法律a Except for one: T a is not a monoid because it does not quite satisfy laws 4 or 5.除了一个: T a不是幺半群,因为它不完全满足定律 4 或 5。

So now we should ask if we can make this into a simpler free monoid, ie one that is an actual monoid.所以现在我们应该问我们是否可以把它变成一个更简单的自由幺半群,即一个真正的幺半群。 The answer is yes.答案是肯定的。 One way is to observe that Conc Unit a and Conc a Unit and Single a should be the same.一种方法是观察Conc Unit aConc a UnitSingle a应该是一样的。 So let's make the first two types unrepresentable:因此,让我们使前两种类型不可表示:

data TInner a = Single a | Conc (TInner a) (TInner a)
data T a = Unit | Inner (TInner a)

A second observation we can make is that there should be no difference between Conc (Conc ab) c and Conc a (Conc bc) .我们可以进行的第二个观察是Conc (Conc ab) cConc a (Conc bc)之间应该没有区别。 This is due to law 5 above.这是由于上述第 5 条。 We can then flatten our tree:然后我们可以展平我们的树:

data TInner a = Single a | Conc (a,TInner a)
data T a = Unit | Inner (TInner a)

The strange construction with Conc forces us to only have a single way to represent Single a and Unit . Conc的奇怪构造迫使我们只有一种方法来表示Single aUnit But we see we can merge these all together: change the definition of Conc to Conc [a] and then we can change Single x to Conc [x] , and Unit to Conc [] so we have:但是我们看到我们可以将所有这些合并在一起:将Conc的定义更改为Conc [a]然后我们可以将Single x更改为Conc [x]并将Unit更改为Conc []所以我们有:

data T a = Conc [a]

Or we can just write:或者我们可以写:

type T a = [a]

And the operations are:操作是:

unit = []
e a = [a]
(•) = append

free f ((*),zero) = f' where
  f' [] = zero
  f' (x:xs) = f x * f' xs

So in Haskell, the list type is called the free monoid.所以在 Haskell 中,列表类型被称为自由幺半群。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM