Skip to content

Instantly share code, notes, and snippets.

@fancellu
Last active February 25, 2021 13:47
Show Gist options
  • Select an option

  • Save fancellu/b927ab4b06e4378b6bc429f485bd50c8 to your computer and use it in GitHub Desktop.

Select an option

Save fancellu/b927ab4b06e4378b6bc429f485bd50c8 to your computer and use it in GitHub Desktop.
Little Monoid/Typeclass example from the ground up (no cats)
object MyMonoid extends App {
import scala.collection.immutable.HashMap
trait Monoid[A] {
def empty: A
def combine(x: A, y: A): A
}
object Monoid {
def apply[A : Monoid]: Monoid[A] = implicitly[Monoid[A]]
}
implicit val intAdditionMonoid: Monoid[Int] = new Monoid[Int] {
def empty: Int = 0
def combine(x: Int, y: Int): Int = x + y
}
implicit val stringAdditionMonoid: Monoid[String] = new Monoid[String] {
def empty: String = ""
def combine(x: String, y: String): String = x + y
}
def combineAll[A : Monoid](list: List[A]): A = list.foldRight(Monoid[A].empty)(Monoid[A].combine)
println(combineAll(List(1,2,3)))
println(combineAll(List("a","b","c")))
final case class Pair[A, B](first: A, second: B)
implicit def pairMonoid[A, B](implicit A: Monoid[A], B: Monoid[B]): Monoid[Pair[A, B]] =
new Monoid[Pair[A, B]] {
def empty: Pair[A, B] = Pair(A.empty, B.empty)
def combine(x: Pair[A, B], y: Pair[A, B]): Pair[A, B] =
Pair(A.combine(x.first, y.first), B.combine(x.second, y.second))
}
println(combineAll(List(Pair(1,"a"), Pair(2,"b"))))
// don't need Monoid for A, we aren't combining them
implicit def mapAdditionMonoid[A,B](implicit B: Monoid[B]): Monoid[HashMap[A,B]] = new Monoid[HashMap[A,B]] {
def empty: HashMap[A,B] = HashMap.empty
def combine(x: HashMap[A,B], y: HashMap[A,B]): HashMap[A,B] = x.merged(y){
case ((k0, v0), (_, v1)) => k0 -> B.combine(v0,v1) // we ignore k1, which will be the same as k0
}
}
println(combineAll(List(HashMap(1->"a",3->"c",2->"222222"), HashMap(2->"b"),HashMap(9->"9999"))))
println(combineAll(List(HashMap(1->Pair(1,"a"),2->Pair(2,"b")),HashMap(1->Pair(100,"a!"),2->Pair(200,"b!"),3->Pair(333,"threethreethree")))))
}
6
abc
Pair(3,ab)
HashMap(1 -> a, 9 -> 9999, 2 -> 222222b, 3 -> c)
HashMap(1 -> Pair(101,aa!), 2 -> Pair(202,bb!), 3 -> Pair(333,threethreethree))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment