Created
March 13, 2012 12:53
-
-
Save oxbowlakes/2028579 to your computer and use it in GitHub Desktop.
Monoid example
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
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