monoids
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:
All- Boolean newtype that combines values using&&Any- Boolean newtype that combines values using||Dual- Inverts the Combine operation of a monoidFirst- Option newtype that combine takes the first element that is presentLast- Option newtype that combine takes the last element that is presentProduct- Numeric newtype that combines values using MultiplicationSum- Numeric newtype that combines values using Addition
Also some generic Semigroups:
Dualinverts the combine operation.Maxexposes a Max that given anOrderwill return the maximum value.Minexposes a Min that given anOrderwill return the minimum value.
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)"