Skip to main content

Monoid

Monoid is a SemiGroup with identity element which guarantees that Monoid complies with left identity law and right identity law.

Left Identity

// Left identity
Monoid[A].append(Monoid[A].zero, A) // is just A
import just.fp._
import just.fp.syntax._

// So
Monoid[List[Int]].append(Monoid[List[Int]].zero, List(1, 2, 3))
// res0: List[Int] = List(1, 2, 3)
// The same as
Monoid[List[Int]].append(List.empty, List(1, 2, 3))
// res1: List[Int] = List(1, 2, 3)

Monoid[Int].append(Monoid[Int].zero, 999)
// res2: Int = 999
// The same as
Monoid[Int].append(0, 999)
// res3: Int = 999

Monoid[String].zero |+| "abc"
// res4: String = "abc"
// The same as
"" |+| "abc"
// res5: String = "abc"

Monoid[Option[Int]].zero.mappend(123.some)
// res6: Option[Int] = Some(value = 123)
// The same as
none[Int].mappend(123.some)
// res7: Option[Int] = Some(value = 123)

Right Identity

// Right identity
Monoid[A].append(A, Monoid[A].zero) // is just A
import just.fp._
import just.fp.syntax._

// So
Monoid[List[Int]].append(List(1, 2, 3), Monoid[List[Int]].zero)
// res8: List[Int] = List(1, 2, 3)
// The same as
Monoid[List[Int]].append(List(1, 2, 3), List.empty)
// res9: List[Int] = List(1, 2, 3)

Monoid[Int].append(999, Monoid[Int].zero)
// res10: Int = 999
// The same as
Monoid[Int].append(999, 0)
// res11: Int = 999

"abc" |+| Monoid[String].zero
// res12: String = "abc"
// The same as
"abc" |+| ""
// res13: String = "abc"

123.some.mappend(Monoid[Option[Int]].zero)
// res14: Option[Int] = Some(value = 123)
// The same as
123.some.mappend(none[Int])
// res15: Option[Int] = Some(value = 123)

Examples

Example use of Monoid

def fold[A : Monoid](as: List[A]): A =
as.foldLeft(Monoid[A].zero)(_ |+| _)

fold(List(1, 2, 3, 4, 5))
// res16: Int = 15

fold(List("abc", "def", "ghi"))
// res17: String = "abcdefghi"

fold(List(1.some, 2.some, none, 4.some, 5.some, none))
// res18: Option[Int] = Some(value = 12)