Monoidを使ってみた
Semigroup(半群)に単位元を加えたものがMonoid(単位的半群)。Semigroupは結合法則を持つ。
ざっくり言うと「足し算のやり方と、ゼロはなんだ?」というのを持っていればMonoid。
import scalaz._ import Scalaz._ object HelloMonoid extends App { case class Hoge(cost: Int, cv: Int) implicit object HogeMonoid extends Monoid[Hoge] { def zero: Hoge = Hoge(0, 0) def append(r1: Hoge, r2: => Hoge): Hoge = Hoge(r1.cost + r2.cost, r1.cv + r2.cv) } Console println Hoge(100, 2) |+| Hoge(50, 3) //Hoge(150,5) val hs = Hoge(100, 2) :: Hoge(200, 3) :: Nil Console println hs.reduce(_ |+| _) //Hoge(300,5) Console println hs.foldLeft(HogeMonoid.zero)(_ |+| _) //Hoge(300,5) case class Foo(s: String, xs: List[Int]) implicit object FooMonoid extends Monoid[Foo] { def zero: Foo = Foo("", List.empty) def append(r1: Foo, r2: => Foo): Foo = Foo(s"${r1.s} and ${r2.s}", r1.xs ::: r2.xs) } val fs = Foo("apple", List(1, 2)) :: Foo("ornge", List(5, 9)) :: Foo("banana", List(0)) :: Nil Console println fs.reduce(_ |+| _) //Foo(apple and ornge and banana,List(1, 2, 5, 9, 0)) }