Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Typeclasses Workshop
/* See: http://underscore.io/blog/posts/2015/06/04/more-on-sealed.html */
sealed trait FrostSpell extends Product with Serializable
case object Blizzard extends FrostSpell
case object Icebolt extends FrostSpell
object FrostSpell {
implicit val ordering: Ordering[FrostSpell] = new Ordering[FrostSpell] {
override def compare(x: FrostSpell, y: FrostSpell): Int = (x,y) match {
case (Blizzard, Icebolt) => 1
case (Icebolt, Blizzard) => -1
case _ => 0
}
}
implicit val spellInstance: Spell[FrostSpell] =
Spell.constructor("Frost!", {
case Blizzard => "Ice shards rain from above!"
case Icebolt => "The ice attackas"
})
}
sealed trait FireSpell extends Product with Serializable
case object Fireball extends FireSpell
object FireSpell {
implicit val spellInstance: Spell[FireSpell] =
Spell.constructor("Fire!", {
case Fireball => "'It does more dmg'"
})
}
object HeroesOfTheLambda {
def attack[A](spell: A)(implicit s: Spell[A]): String = s.attack(spell)
}
trait Spell[A] {
val name: String
def attack(spell: A): String
}
object Spell {
def apply[A](implicit s: Spell[A]): Spell[A] = s
def constructor[A](_name: String, _attack: A => String): Spell[A] = new Spell[A] {
val name = _name
def attack(spell: A): String = _attack(spell)
}
}
trait Monoid[A] {
def zero: A
def append(x: A, y: A): A
}
object Monoid {
def constructor[A](z: A, f: (A, A) => A): Monoid[A] =
new Monoid[A] {
override def zero: A = z
override def append(x: A, y: A): A = f(x, y)
}
implicit val intInstance = constructor[Int](0, _ + _)
implicit val stringInstance = constructor[String]("", _ ++ _)
}
object adding {
def reduce[A](xs: List[A])(implicit m: Monoid[A]): A = xs.foldLeft(m.zero)(m.append)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.