monoid同态到底是什么?

zer*_*ing 60 haskell functional-programming scala category-theory monoids

我已经从Monoid Morphisms,Products和Coproducts中阅读了有关Monoid同态的知识,并且无法理解100%。

作者说(强调原文):

length函数从映射到StringInt 同时保留类半体结构。这种以一种保存方式从一个单半体映射到另一个单半体的函数称为单半体同态。通常,对于monoid MN,是同态f: M => N,以及所有值 x:My:M以下等式成立:

f(x |+| y) == (f(x) |+| f(y))

f(mzero[M]) == mzero[N]
Run Code Online (Sandbox Code Playgroud)

他的意思是说,由于数据类型StringInt是monoid ,并且函数length映射String => Int保留了monoid结构(Int是monoid),所以称为monoid同态,对吗?

Wil*_*sem 72

他的意思是,数据类型String和Int是monoid。

String也不Int是monoid。一个单面体是一个三元组(S,⊕,e),其中⊕是一个二元运算符⊕:S×S→S,因此对于所有元素a,b,c∈S都持有(a⊕b)⊕c =a⊕(b⊕c),并且e∈S是一个“身份元素”,因此a⊕e=e⊕a= aStringInt是类型,因此基本上是一组值,但不是三元组。

文章说:

让我们以String串联Int加法为例,说明具有关系的类齐半体

因此,作者显然也提到了二元运算符((++)String(+)的情况下Int)。身份(在String0情况下为空字符串Int)保持隐式;在非正式英语语篇中,将身份留给读者练习是很常见的。

现在假设我们有两个单曲面结构(M,⊕,e m(N,⊗,e n,则函数f:M→N(like length)称为单曲面同态 [wiki],因为它认为f (M 1 ⊕m 2)= F(M 1)⊗f(米2为所有元素中号1,米2 ∈M和该映射还保留了身份元素:F(è )= E ñ

例如length :: String -> Int是幺同态,因为我们可以考虑类群String(++)""Int(+)0。它认为:

  1. length (s1 ++ s2) == length s1 + length s2(对于所有Strings s1s2);和
  2. length "" == 0


slo*_*ouc 19

数据类型本身不能是monoid。对于一个monoid,您需要一个数据类型T和另外两件事:

  • 一个关联的二进制操作,我们称它为|+|,它接受两个type元素,T并产生一个type元素T
  • 我们将其称为type 的标识元素,以便对于每个type 元素都具有以下内容:TitTt |+| i = i |+| t = t

这是一个monoid的例子:

  • 一组整数,其运算=加法且标识= 0
  • 一组整数,其中运算=乘法,恒等式=一个
  • 一组具有操作=附加和标识=空列表的列表
  • 具有操作=串联和标识=空字符串的字符串集

类半同态

通过将字符串并置的monoid应用于.length其所有元素,可以将其转换为整数加法的monoid 。这两个集合都构成一个半体。顺便说一句,请记住,我们不能只说“一组整数构成一个单半体”。我们必须选择一个关联操作和一个相应的标识元素。如果将除法作为运算,则会打破第一条规则(而不是生成整数类型的元素,而可能会生成float / double类型的元素)。

方法length使我们能够从一个monoid(字符串串联)转到另一个monoid(整数加法)。如果这样的操作还保留了类单态结构,则认为它是一个类单态同态

保留结构意味着:

length(t1 |+| t2) = length(t1) |+| length(t2)

and

length(i) = i'
Run Code Online (Sandbox Code Playgroud)

其中t1t2代表“源” monoid的元素,是“源” monoid i的标识,并且i'是“目标” monoid的标识。您可以自己尝试一下,看看length确实是对字符串串联Monoid的保留结构的操作,而例如,indexOf("a")则不是。

类半同构

如所示,length将所有字符串映射到其对应的整数,并形成一个以加法运算为运算符和以零作为标识的Monoid。但是我们不能返回-对于每个字符串,我们都可以计算出它的长度,但是在给定长度的情况下,我们无法重构“原始”字符串。如果可以的话,“前进”的操作与“前进”的操作相结合,将形成一个单面体同构

同构意味着能够来回往返而不会丢失任何信息。例如,如前所述,列表在附加为操作和空列表作为标识元素的情况下形成一个monoid。我们可以从“附加列表下的” monoid转到“附加矢量下的” monoid,然后返回而不会丢失任何信息,这意味着运算.toVector.toList一起形成同构。鲁纳尔在课文中提到的同构的另一个例子是StringList[Char]