google到数学里定义的群(group): G为非空集合,如果在G上定义的二元运算 *,满足

(1)封闭性(Closure):对于任意a,b∈G,有a*b∈G
(2)结合律(Associativity):对于任意a,b,c∈G,有(a*b)*c=a*(b*c)
(3)幺元 (Identity):存在幺元e,使得对于任意a∈G,e*a=a*e=a
(4)逆元:对于任意a∈G,存在逆元a^-1,使得a^-1*a=a*a^-1=e

则称(G,*)是群,简称G是群。

如果仅满足封闭性和结合律,则称G是一个半群(Semigroup);如果仅满足封闭性、结合律并且有幺元,则称G是一个含幺半群(Monoid)。

相比公式还是用代码表达更容易理解,下面表示一个半群(semigroup):

trait SemiGroup[T] {
def append(a: T, b: T): T
}

特质SemiGroup,定义了一个二元操作的方法append,可以对半群内的任意2个元素结合,且返回值仍属于该半群。

我们看具体的实现,一个Int类型的半群实例:

object IntSemiGroup extends SemiGroup[Int] {
def append(a: Int, b: Int) = a + b
} // 对2个元素结合
val r = IntSemiGroup.append(1, 2)

现在在半群的基础上,再增加一个幺元(Identity,也翻译为单位元),吐槽一下,幺元这个中文不知道最早谁起的,Identity能表达的意义(同一、恒等)翻译到中文后完全消失了。

trait Monoid[T] extends SemiGroup[T] {
// 定义单位元
def zero: T
}

上面定义了一个幺半群,继承自半群,增加了一个单位元方法,为了容易理解,我们用zero表示,半群里的任何元素a与zero结合,结果仍是a本身。

构造一个Int类型的幺半群实例:

object IntMonoid extends Monoid[Int] {
// 二元操作
def append(a: Int, b: Int) = a + b
// 单位元
def zero = 0
}

构造一个String类型的幺半群实例:

object StringMonoid extends Monoid[String] {
def append(a: String, b: String) = a + b
def zero = ""
}

再构造一个复杂点的 List[T] 的幺半群工厂方法:

def listMonoid[T] = {
new Monoid[List[T]] {
def zero = Nil
def append(a: List[T], b: List[T]) = a ++ b
}
}

OK,现在我们已经了解了幺半群是什么样了,但它有什么用?

http://hongjiang.info/semigroup-and-monoid/

我所理解的monad(1):半群(semigroup)与幺半群(monoid)的更多相关文章

  1. 我所理解的monad(4):函子(functor)是什么--可把范畴简单的看成高阶类型

    大致介绍了幺半群(monoid)后,我们重新回顾最初引用wadler(haskell委员会成员,把monad引入haskell的家伙)的那句话: 现在我们来解读这句话中包含的另一个概念:自函子(End ...

  2. Scalaz(25)- Monad: Monad Transformer-叠加Monad效果

    中间插播了几篇scalaz数据类型,现在又要回到Monad专题.因为FP的特征就是Monad式编程(Monadic programming),所以必须充分理解认识Monad.熟练掌握Monad运用.曾 ...

  3. js函数式编程术语总结 - 持续更新

    参考文档1 参考文档2 函数式编程术语 高阶函数 Higher-Order Functions 以函数为参数的函数 返回一个函数的函数 函数的元 Arity 比如,一个带有两个参数的函数被称为二元函数 ...

  4. monads-are-elephants(转)

    介绍monads有点像互联网时代的家庭手工业.我想 “为什么要反对传统?”,但这篇文章将以Scala对待monads的方式来描述. 有个古老的寓言,讲述了几个瞎子第一次摸到大象.一个抱着大象的腿说:“ ...

  5. C# Monads的实现(二)

    再谈continuation monad 上一篇中我们已经介绍了continuation monad,但是这个monad与Identity,Maybe,IEnumerable monads稍微难于理解 ...

  6. Haskell语言学习笔记(25)MonadState, State, StateT

    MonadState 类型类 class Monad m => MonadState s m | m -> s where get :: m s get = state (\s -> ...

  7. Scalaz(50)- scalaz-stream: 安全的无穷运算-running infinite stream freely

    scalaz-stream支持无穷数据流(infinite stream),这本身是它强大的功能之一,试想有多少系统需要通过无穷运算才能得以实现.这是因为外界的输入是不可预料的,对于系统本身就是无穷的 ...

  8. Scalaz(46)- scalaz-stream 基础介绍

    scalaz-stream是一个泛函数据流配件库(functional stream combinator library),特别适用于函数式编程.scalar-stream是由一个以上各种状态的Pr ...

  9. Category Theory: 01 One Structured Family of Structures

    Category Theory: 01 One Structured Family of Structures 这次看来要放弃了.看了大概三分之一.似乎不能够让注意力集中了.先更新吧. 群的定义 \( ...

随机推荐

  1. CoreData 从入门到精通(五)CoreData 和 TableView 结合

    我们知道 CoreData 里存储的是具有相同结构的一系列数据的集合,TableView 正好是用列表来展示一系列具有相同结构的数据集合的.所以,要是 CoreData 和 TableView 能结合 ...

  2. Java7里try-with-resources分析--转

    原文地址:http://blog.csdn.net/hengyunabc/article/details/18459463 这个所谓的try-with-resources,是个语法糖.实际上就是自动调 ...

  3. sql server Delete误操作后如何恢复数据

    声明:本文是根据别人的经验https://blog.csdn.net/dba_huangzj/article/details/8491327写的总结 说明:update和delete时没有加where ...

  4. CTSC2012 熟悉的文章 广义后缀自动机_单调队列

    没啥难的,主要是单调队列忘了咋求了QAQ... Code: #include <cstdio> #include <algorithm> #include <cstrin ...

  5. h5实现 微信的授权登录

    本文重点 判断是不是微信环境 localstorage设置一个值 微信授权登录 获取一个时间戳 new Date().getTime() const wx = (function () { retur ...

  6. Python数据分析前提-----pandas

    1.read_csv(url):读取数据 2.help(read_csv):打印函数相关用法 3.数据名.dtypes:读取数据的类型(int.float……) 4.type(数据名):读取所有数据的 ...

  7. 多任务-进程之进程池Pool

    1.什么是池? 首先从字面上看,池代表着一个容器,用来承载着某些内容的容器,了解到这里,就对进程池有了一个初步的轮廓. 2.什么是进程池Pool? (1)利用现实中的事物来理解: 对于小白初学者,接触 ...

  8. How Javascript works (Javascript工作原理) (六) WebAssembly 对比 JavaScript 及其使用场景

    个人总结: 1.webassembly简介:WebAssembly是一种用于开发网络应用的高效,底层的字节码.允许在网络应用中使用除JavaScript的语言以外的语言(比如C,C++,Rust及其他 ...

  9. ES 新增字符串方法

    话不多说,直接开鲁 1. startsWith() 作用: 检测字符串以什么开头 实例: let str = "www.qjzzj.top"; console.log(str.st ...

  10. CF666E Forensic Examination(后缀自动机+线段树合并)

    给你一个串S以及一个字符串数组T[1..m],q次询问,每次问S的子串S[pl..pr]在T[l..r]中的哪个串里的出现次数最多,并输出出现次数. 如有多解输出最靠前的那一个. 我们首先对m个字符串 ...