I'm struggling to come up with a good mental model for when is a problem a good fit for the Type Classes pattern?
Recently I was working with a model like
sealed trait FooBar
case class Foo() extends FooBar
case class Bar() extends FooBar
Intuitively I would simply pattern match
def handle(x: FooBar) = x match {
case f: Foo => println("foo")
case b: Bar => println("bar")
}
or use subtyping/overloading explicitly like
object Overloading {
def handle(x: Foo) = println("foo")
def handle(x: Bar) = println("bar")
}
On the other hand, the type class approach is verbose and I don't see any benefit from using it:
trait FooBarThing[T <: FooBar] {
def handle(x: T): Unit
}
object TypeClass {
implicit object HandleFoo extends FooBarThing[Foo] {
def handle(x: Foo) = println("foo")
}
implicit object HandleBar extends FooBarThing[Bar] {
def handle(x: Bar) = println("bar")
}
def process[T <: FooBar](x: T)(implicit ev: FooBarThing[T]): Unit = {
ev.handle(x)
}
}
I've found many articles explaining how to write type classes but not much on when?
Aucun commentaire:
Enregistrer un commentaire