Skip to content

Instantly share code, notes, and snippets.

@oxbowlakes
Created March 13, 2012 12:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save oxbowlakes/2028579 to your computer and use it in GitHub Desktop.
Save oxbowlakes/2028579 to your computer and use it in GitHub Desktop.
Monoid example
trait Monoid[A] {
def identity: A
def mplus(a1: A, a2: A): A
}
object Monoid {
implicit val IntMonoid = new Monoid[Int] {
def identity = 0
def mplus(a1: Int, a2: Int) = a1 + a2
}
implicit val DoubleMonoid = new Monoid[Double] {
def identity = 0D
def mplus(a1: Double, a2: Double) = a1 + a2
}
private def monoid[A: Monoid] = implicitly[Monoid[A]]
implicit def OptionMonoid[A: Monoid] = new Monoid[Option[A]] {
def identity = None
def mplus(o1: Option[A], o2: Option[A]) = (o1, o2) match {
case (Some(a1), Some(a2)) => Some(monoid[A].mplus(a1, a2))
case (x @ Some(_), None) => x
case (None, x @ Some(_)) => x
case (None, None) => None
}
}
implicit def PairMonoid[A: Monoid, B: Monoid] = new Monoid[(A, B)] {
def identity = (monoid[A].identity, monoid[B].identity)
def mplus(a1: (A, B), a2: (A, B)) = (monoid[A].mplus(a1._1, a2._1), monoid[B].mplus(a1._2, a2._2))
}
implicit def Function1Monoid[A, B: Monoid] = new Monoid[A => B] {
def identity = a => monoid[B].identity
def mplus(a1: A => B, a2: A => B) = a => monoid[B].mplus(a1(a), a2(a))
}
implicit def MapMonoid[A, B: Monoid] = new Monoid[Map[A, B]] {
def identity = Map.empty
def mplus(a1: Map[A, B], a2: Map[A, B]) = {
val intersection = a1.keySet & a2.keySet
(a1 filterKeys (k => !intersection(k))) ++ (a2 filterKeys (k => !intersection(k))) ++ (intersection map (k => k -> monoid[B].mplus(a1(k), a2(k)))).toMap
}
}
def some[A](a: A): Option[A] = Some(a)
def none[A]: Option[A] = None
trait Id[A] {
val value: A
def mplus(b: A)(implicit m: Monoid[A]) = m.mplus(value, b)
}
object Syntax {
implicit def mkId[A](a: A) = new Id[A] { val value = a }
}
import Syntax._
some(1) mplus none[Int]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment