Skip to content

Instantly share code, notes, and snippets.

@AugustNagro
Created February 3, 2017 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AugustNagro/13bf6ec2c8d984e25ccf7a09694f87e9 to your computer and use it in GitHub Desktop.
Save AugustNagro/13bf6ec2c8d984e25ccf7a09694f87e9 to your computer and use it in GitHub Desktop.
Example Semigroup and Monoid Typeclasses
// Paste this into the scala shell after typeing `:paste`
trait Semigroup[A] {
def combine(x: A, y: A): A
}
object Semigroup {
def apply[A](implicit ev: Semigroup[A]): Semigroup[A] = ev
private implicit class SemigroupOps[A](val lhs: A) extends AnyVal {
def combine(rhs: A)(implicit semi: Semigroup[A]): A =
semi.combine(lhs, rhs)
/** Alias for `combine` */
def |+|(rhs: A)(implicit semi: Semigroup[A]): A =
semi.combine(lhs, rhs)
}
trait SemigroupSyntax {
implicit def toSemigroupOps[A: Semigroup](lhs: A): SemigroupOps[A] =
new SemigroupOps(lhs)
}
object syntax extends SemigroupSyntax
implicit val intSemigroup: Semigroup[Int] = (a, b) => a + b
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
object Monoid {
def apply[A](implicit ev: Monoid[A]): Monoid[A] = ev
object syntax extends Semigroup.SemigroupSyntax
implicit val stringMonoid: Monoid[String] = new Monoid[String] {
def combine(x: String, y: String): String = x + y
def empty: String = ""
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment