Last active
September 27, 2018 11:29
-
-
Save loicdescotte/abb12bb623c87aa2c0038c5db28d82c1 to your computer and use it in GitHub Desktop.
Scala Typeclass Example
This file contains 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
//typeclass example | |
//Note : List already has a sum method working the same way | |
//List(1,2,3).sum returns 6 | |
//but this example is simpler | |
// Monoid = summable + neutral element | |
trait Monoid[T] { | |
def combine(a: T, b: T): T | |
def empty: T | |
} | |
//default instances | |
object Monoid { | |
implicit val intMonoid: Monoid[Int] = new Monoid[Int] { | |
override def combine(a: Int, b: Int) = a +b | |
override def empty = 0 | |
} | |
implicit val stringMonoid: Monoid[String] = new Monoid[String] { | |
override def combine(a: String, b: String) = a +b | |
override def empty = "" | |
} | |
} | |
//add sumAll method to Scala List type | |
implicit class ListWithSumAll[T](list: List[T]){ | |
def combineAll()(implicit monoid: Monoid[T]): T = | |
list.foldLeft(monoid.empty)((sum, element) => monoid.combine(sum, element)) | |
} | |
List(1,2,3).combineAll //6 | |
List("1","2","3").combineAll //123 | |
// add your instances here | |
case class Color(red: Int, green: Int, blue: Int) | |
implicit val colorMonoid: Monoid[Color] = new Monoid[Color] { | |
override def combine(c1: Color, c2: Color) = { | |
val red = Math.min(c1.red + c2.red, 255) | |
val green = Math.min(c1.green + c2.green, 255) | |
val blue = Math.min(c1.blue + c2.blue, 255) | |
Color(red, blue, green) | |
} | |
override def empty = Color(0,0,0) | |
} | |
List(Color(10,10,10), Color(200, 255, 10), Color(20, 55, 1)).combineAll // Color(62,66,32) | |
List[Color](Color(10,10,10)).combineAll // Color(10,10,10) | |
List[Color]().combineAll // Color(0,0,0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment