正确使用术语Monoid [英] Correct use of term Monoid

查看:98
本文介绍了正确使用术语Monoid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从下面的例子中,我认为 String 在连接操作下定义了monoid是正确的,因为它是一个关联二元操作, String 碰巧有一个标识元素,它是一个空字符串

 阶> (+Jane)+Doe==+(Jane+Doe)
res0:布尔值= true

从我最近在这个主题上阅读过的不同文本看来,正确使用术语幺半群是幺半群实际上是类型的组合(在这种情况下 String )和一个monoid类型的实例,它定义了操作和标识元素。



例如,下面是一个理论上的 Monoid 类型和它的一个具体实例,似乎通常在各种书籍/文章中定义: -



pre $ code $特性Monoid [A] {
def op(a1:A,a2:A):A
def zero: A

$ b $ val stringMonoid = new Monoid [String] {
def op(a1:String,a2:String)= a1 + a2
val zero =
}

我知道我们不需要 trait Monoid [A] stringMonoid 在核心(Scala或者Java)库中定义为支持我的REPL输出,这个例子只是一个理解monoid抽象概念的工具。

我的问题(我很可能想太多)是纯粹主义的定义。我知道底层的 java.lang.String (或者更确切地说是 StringBuilder )已经定义了关联操作,但我确实不要认为在任何地方定义了身份元素的明确定义(在本例中只是一个空字符串)。



问题: -

字符串一个monoid隐式地在串联操作下,仅仅因为我们碰巧知道使用空字符串提供了身份?或者它是一种类型的身份元素的明确定义是不必要的,因为它被归类为幺半群(在特定的关联二元操作下)。

解决方案

我认为你已经理解了这个概念,并且确实对它想得太多 b
$ b

幺半群是一个三元组,它们在数学中说:一个集合(考虑一个具有它的值的类型),一个关联二元运算符和一个中性元素。你定义了这样的三元组 - 你定义了一个monoid。所以对于


的答案是 String 提供了标识符?


blockquote>

仅仅是 yes 。您命名了set,​​关联二元运算和中性元素 - 宾果!您有一个monoid!关于


已经定义了关联操作,但我不认为有一个明确定义的元素




有一点你可以在 String 上选择不同的关联操作及其相应的中性元素,并定义各种monoid。级联不是像 String 上的某种正统联合操作来定义monoid,可能是最明显的。

如果您将表格定义为有四条腿且表面平坦的表,那么符合此定义的任何东西都是 不管制作的材料和其他可变特征如何。现在,你什么时候需要证明它明确是一张表?只有当你需要使用它的表格属性时,说出卖它和宣传你可以把东西放在上面,它们不会脱落,因为表面保证是平的 horizo​​ntal



对不起,如果这个例子有点愚蠢,我在这种类比中不是很好。我希望它仍然有帮助。




现在关于实例化所提及的理论 Monoid 类型。这种类型通常称为类型类。这种类型本身(可以用各种方式定义)以及它的实例都不需要调用三元(String,(_ ++ _),)一个monoid和原因将它作为一个monoid(即使用一般monoid属性)。它实际使用的是特别多态性。在斯卡拉它是用implicits完成的。例如,可以定义一个多态函数

  def fold [M](seq:Seq [M])(隐式m:Monoid [M]):M = seq match {
case Seq.empty => m.zero
case(h +:t)=> m.op(h,fold(t))
}

然后如果你的<$无论何时使用 fold [String] ,c $ c> stringMonoid 值被声明为隐式val c>和 stringMonoid 在范围内,它将使用它的 op 里面。相同的 fold 定义可用于 Monoid [...] 的其他实例。



另一个话题是当你有几个 Monoid [String] 的实例时会发生什么。阅读 Scala在何处查找隐含信息?


From the following example, I think it is correct to say that String defines a monoid under the concatenation operation since it is an associative binary operation and String happens to have an identity element which is an empty string "".

scala> ("" + "Jane") + "Doe" ==  "" + ("Jane" + "Doe")
res0: Boolean = true

From the various texts I have been reading on the subject lately, it seems that the correct use of the term monoid is that the monoid is actually a combination of both the type (in this case String) and an instance of some monoid type which defines the operation and identity element.

For example, here is a theoretical Monoid type and a concrete instance of it as seems to be commonly defined in various books/articles:-

trait Monoid[A] { 
  def op(a1: A, a2: A): A 
  def zero: A 
} 

val stringMonoid = new Monoid[String] { 
  def op(a1: String, a2: String) = a1 + a2 
  val zero = "" 
}

I know that we do not need trait Monoid[A] nor stringMonoid to be defined in the core (Scala, or rather Java) library to support my REPL output and that the example is just a tool to understand the abstract concept of a monoid.

My issue (and I am very possibly thinking about it way too much) is the purist definition. I know that the underlying java.lang.String (or rather StringBuilder) already defines the associative operation, but I do not think that there is an explicit definition of the identity element (in this case just an empty string "") defined anywhere.

Question:-

Is String a monoid under the concatenation operation implicitly, just because we happen to know that using an empty string "" provides the identity? Or is it that an explicit definition of the identity element for a type is unnecessary for it to be classed as a monoid (under a particular associative binary operation).

解决方案

I think that you already understand the concept right and indeed "think too much" about it (;

A monoid is a triplet as they say in mathematics: a set (think of a type with its values), an associative binary operator on it and a neutral element. You define such triple — you define a monoid. So the answer to

Is String a monoid under the concatenation operation implicitly, just because we happen to know that using an empty string "" provides the identity?

is simply yes. You named the set, the associative binary operation and the neutral element — bingo! You got a monoid! About

already defines the associative operation, but I do not think that there is an explicit definition of the identity element

there's a bit of confusion. You can choose different associative operations on String with their corresponding neutral elements and define various monoids. Concatenation is not like some kind of "orthodox" associative operation on String to define monoid, just, probably, the most obvious.

If you define a table as something "with four legs and a flat horizontal surface on them", then anything that fits this definition is a table, regardless of the material it's made and other variable characteristics. Now, when do you need to "certify" it explicitly is a table? Only when you need to use its "table-properties", say if to sell it and advertise that you can put things on it and they won't fall off, because the surface is guaranteed to be flat and horizontal.

Sorry, if the example is kind of stupid, I'm not very good in such analogies. I hope it is still helpful.


Now about instantiating the mentioned "theoretical Monoid type". Such types are usually called a type class. Neither existence of such type itself (which can be defined in various ways), nor its instance are necessary to call the triple (String, (_ ++ _), "") a monoid and reason about it as a monoid (i.e. use general monoid properties). What it is actually used for is ad-hoc polymorphism. In Scala it is done with implicits. One can, for example, define a polymorphic function

def fold[M](seq: Seq[M])(implicit m: Monoid[M]): M = seq match {
  case Seq.empty => m.zero
  case (h +: t)  => m.op(h, fold(t))
}

Then if your stringMonoid value is declared as implicit val, whenever you use fold[String] and stringMonoid is in scope, it will use its zero and op inside. Same fold definition will work for other instances of Monoid[...].

Another topic is what happens when you have several instances of Monoid[String]. Read Where does Scala look for implicits?.

这篇关于正确使用术语Monoid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆