Last active
April 28, 2018 16:43
-
-
Save JoolsF/b1f92a7957b4ea91ae2c569f11d0912e to your computer and use it in GitHub Desktop.
monoid example 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * A monoid is a type with a combine operation of type (A, A) => A | |
| * and an identity operation of type A | |
| * | |
| * Note that a semgigroup is just the combine part of a Monoid. | |
| * Here we have split the type up into traits as some types | |
| * for which we cannot define an identity element. | |
| */ | |
| trait Semigroup[A] { | |
| def combine(x: A, y: A): A | |
| } | |
| trait Monoid[A] extends Semigroup[A] { | |
| def empty: A | |
| } | |
| object Monoid { | |
| def apply[A](implicit monoid: Monoid[A]) = | |
| monoid | |
| } | |
| /** | |
| * It follows the following laws. | |
| * It must be associative and follow the identity law | |
| */ | |
| 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) | |
| } | |
| object BooleanMonoidInstances { | |
| implicit def and = new Monoid[Boolean] { | |
| override def combine(x: Boolean, y: Boolean): Boolean = x && y | |
| override def empty: Boolean = true | |
| } | |
| implicit def or = new Monoid[Boolean] { | |
| override def combine(x: Boolean, y: Boolean): Boolean = x || y | |
| override def empty: Boolean = false | |
| } | |
| implicit def xor = new Monoid[Boolean] { | |
| override def combine(x: Boolean, y: Boolean): Boolean = x ^ y | |
| override def empty: Boolean = false | |
| } | |
| } | |
| /** | |
| * Monoids in cats | |
| */ | |
| import cats.Monoid | |
| import cats.Semigroup | |
| import cats.instances.string._ | |
| Monoid[String].combine("hello ","world ") // hello world | |
| Monoid[String].empty // "" | |
| // if we dont need empty we can write | |
| Semigroup[String].combine("hello ","world ") | |
| // we can assemble a Monoid[Option[String]] as follows | |
| import cats.instances.option._ | |
| Monoid[Option[String]].combine(None, Some("hello world")) //Some(hello world) | |
| // syntax | |
| import cats.syntax.semigroup._ //for the |+| syntax | |
| import cats.instances.int._ | |
| 1 |+| 2 |+| 3 |+| Monoid[Int].empty // 6 | |
| import cats.Monoid | |
| import cats.instances.string._ | |
| Monoid[String].combine("hello ", "world ") // hello world | |
| Monoid[String].empty // "" | |
| // if we dont need empty we can write | |
| import cats.Semigroup | |
| Semigroup[String].combine("hello ", "world ") | |
| // we can assemble a Monoid[Option[String]] as follows | |
| import cats.instances.option._ | |
| Monoid[Option[String]].combine(None, Some("hello world")) //Some(hello world) | |
| // syntax | |
| import cats.syntax.semigroup._ // for |+| | |
| import cats.instances.int._ | |
| 1 |+| 2 |+| 3 |+| Monoid[Int].empty // 6 | |
| import cats.instances.map._ // for Monoid | |
| val map1 = Map("a" -> 1, "b" -> 2) | |
| val map2 = Map("b" -> 3, "d" -> 4) | |
| map1 |+| map2 | |
| // res3: Map[String,Int] = Map(b -> 5, d -> 4, a -> 1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment