monoids

Continuous Integration Maven Central

Monoids is a library of a set of generic Monoid and Semigroup types that are very useful for abstract programming.

This library exposes some generic Monoids:

Also some generic Semigroups:

Quick Start

To use this project in an existing SBT project with Scala 2.12 or a later version, add the following dependencies to your build.sbt depending on your needs:

libraryDependencies ++= Seq(
  "org.typelevel" %%% "monoids" % "<version>"
)

Examples

First some imports.

import cats._
import cats.implicits._
import org.typelevel.monoids._

The boolean monoids lift boolean algebras into monoids.

List(true, true, true).foldMap(All(_))

List(true, false, true).foldMap(All(_))

List(false, false, false).foldMap(All(_))

List(false, true, false).foldMap(All(_))

Sum/Product allow explicit composition of Numeric values

List(1,2,3,6).foldMap(Sum(_))
List(1,2,3,6).foldMap(Product(_))

First/Last Option wrappers allow composition based on position and existence. So First takes the first value that is non empty down the chain of composition

First(1.some) |+| First(2.some)
First(1.some) |+| First(Option.empty[Int])
First(Option.empty[Int]) |+| First(2.some)
First(Option.empty[Int]) |+| First(2.some) |+| First(3.some)
First(Option.empty[Int]) |+| First(Option.empty[Int]) |+| First(3.some)

Last(1.some) |+| Last(2.some)
Last(1.some) |+| Last(Option.empty[Int])
Last(Option.empty[Int]) |+| Last(2.some)
Last(1.some) |+| Last(2.some) |+| Last(Option.empty[Int])
Last(1.some) |+| Last(Option.empty[Int]) |+| Last(Option.empty[Int])

As mentioned above, Dual inverts the combine operation of a Monoid. That could be well observed for the non-commutative algebra.

Dual("World") |+| Dual("Hello")
Dual("Hello") |+| Dual("World")

Dual(1) |+| Dual(2)
Dual(2) |+| Dual(1)

Scala 3 support

Scala 3 support implemented using opaque types. Due to limitation in opaque types toString() method on every monoids type produce unwrapped-value without wrapper-type information, e.g.:

val resultString = List(true, true, true).foldMap(All(_)).toString // "true"

That behaviour differs from Scala 2 one - toString() method would produce wrapped-value:

val resultString = List(true, true, true).foldMap(All(_)).toString // "All(true)"

So it's recommended to use Show[T].show from cats for converting to string. Its behaviour is consistent for both Scala 2 and Scala 3:

val resultString = List(true, true, true).foldMap(All(_)).show // "All(true)"