Skip to content

Instantly share code, notes, and snippets.

@lemonxah
Last active September 30, 2016 09:10
Show Gist options
  • Save lemonxah/6cb65bfef2e5537507900ec74997fc47 to your computer and use it in GitHub Desktop.
Save lemonxah/6cb65bfef2e5537507900ec74997fc47 to your computer and use it in GitHub Desktop.
object ops {
implicit class SemigroupOps[F](val self: F)(implicit val F: Semigroup[F]) {
def |+|(other: => F): F = F.combine(self, other)
}
}
import ops._
trait Semigroup[A] {
def combine(a1: A, a2: A): A
}
trait Monoid[A] extends Semigroup[A] {
def zero: A
}
case class TeamScore(goals: Int, penalties: Int)
case class Soccer(score: TeamScore)
object Main extends App {
implicit val intsg = new Semigroup[Int] {
override def combine(a1: Int, a2: Int): Int = a1 + a2
}
implicit val teamscoremonoid = new Monoid[TeamScore] {
override def zero: TeamScore = TeamScore(0,0)
override def combine(a1: TeamScore, a2: TeamScore): TeamScore = TeamScore(a1.goals |+| a2.goals, a1.penalties |+| a2.penalties)
}
implicit val scoremonoid = new Monoid[Soccer] {
override def zero: Soccer = Soccer(TeamScore(0,0))
override def combine(a1: Soccer, a2: Soccer): Soccer = Soccer(a1.score |+| a2.score)
}
def getScores[A](scores: List[A])(implicit M: Monoid[A]): A = {
scores.fold(M.zero)(_ |+| _)
}
val score = getScores(List(Soccer(TeamScore(1,0)), Soccer(TeamScore(2,1)), Soccer(TeamScore(3,2))))
val score2 = getScores(List(TeamScore(1,0), TeamScore(2,1), TeamScore(3,2)))
println(s"$score")
println(s"$score2")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment