Skip to content

Instantly share code, notes, and snippets.

@tachesimazzoca
Last active May 5, 2018 00:22
Show Gist options
  • Save tachesimazzoca/b50c03804868902541c2eec1510fb201 to your computer and use it in GitHub Desktop.
Save tachesimazzoca/b50c03804868902541c2eec1510fb201 to your computer and use it in GitHub Desktop.
Type Classes in Scala
trait Semigroup[A] {
def combine(a: A, b: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
object Monoid {
def apply[A : Monoid]: Monoid[A] = implicitly[Monoid[A]]
}
implicit val intMonoidInstance = new Monoid[Int] {
def empty: Int = 0
def combine(a: Int, b: Int): Int = a + b
}
implicit val stringMonoidInstance = new Monoid[String] {
def empty: String = ""
def combine(a: String, b: String): String = a + b
}
case class Pair[A, B](x: A, y: B)
implicit def pairMonoidInstance[A : Monoid, B : Monoid] =
new Monoid[Pair[A, B]] {
def empty: Pair[A, B] =
Pair(Monoid[A].empty, Monoid[B].empty)
def combine(a: Pair[A, B], b: Pair[A, B]): Pair[A, B] =
Pair(
Monoid[A].combine(a.x, b.x),
Monoid[B].combine(a.y, b.y)
)
}
def combineAll[A : Monoid](xs: List[A]): A =
xs.foldRight(Monoid[A].empty)(Monoid[A].combine)
combineAll(List(1, 2, 3, 4))
combineAll(List("foo", "bar", "baz"))
combineAll(List(Pair(1, 2), Pair(3, 4)))
combineAll(List(Pair(1, "foo"), Pair(2, "bar")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment