Monoids and Semigroups

お久しぶりです。一週間ちょっと前にコロナに感染してから常に身体が怠くて頭も重いから仕事でもプライベートでも何もやる気になりません。

ただ、このままずっとベッドの上で寝ていても良くないので、Scala with Catsを読み始めました。

www.scalawithcats.com

備忘録としてまとめておきます。

Monoid

型AのMonoidは以下の特性?を持ちます。

  • (A, A) => A の組み合わせの操作: combine
  • Aの空要素: empty

Scalaのコードで表すと以下の通り。

trait Monoid[A] {
  def combile(x: A, y: A): A
  def empty: A
}

Monoidにはいくつかの法則があります。

  • combineAssociative でなければならない
  • emptyIdentity Element でなければならない

Associative / Identity Element とは、具体的には以下のような法則です。

def associativeLaw[A](x: A, y: A, z: A)(implicit m: Monoid[A]): Boolean = {
  m.combine(x, m.combine(y, z)) == m.combine(m.combine(x, y), z)
}

def identityLaw[A](x: A)(implicit m: Monoid[A]): Boolean = {
  (m.combine(x, m.empty) == x) && (m.combine(m.empty, x) == x)
}

Semigroup

Semigroup(圏論で半群と呼ぶらしい)は、Monoidの結合部分(combine)のことを指します。

CatsのMonoidは以下のように定義されています。

trait Semigroup[A] {
  def combine(x: A, y: A): A
}

trait Monoid[A] extends Semigroup[A] {
  def empty: A
}