Overloading generic event handlers in Scala

reification, scala, type-erasure

Solution

I don't know of a way to do it in one class (except by making `Event` an ADT and defining handle to accept a parameter of type `Event`. But that would take away the kind of typesafety you seem to be looking for).

I'd suggest using type-class pattern instead.

trait Handles[-A, -E <: Event] {
  def handle(a: A, event: E)
}

trait Event {
  ...
}
class InventoryItemDeactivation(val id: UUID) extends Event
class InventoryItemCreation(val id: UUID, val name: String) extends Event

class InventoryListView {
  ...
}

implicit object InventoryListViewHandlesItemCreation extends 
    Handles[InventoryListView, InventoryItemCreation] = {
  def handle(v: InventoryListView, e: InventoryItemCreation) = {
    ...
  }
}

implicit object InventoryListViewHandlesItemDeactivation extends 
    Handles[InventoryListView, InventoryItemDeactivation] = {
  def handle(v: InventoryListView, e: InventoryItemDeactivation) = {
    ...
  }
}

def someMethod[A, E <: Event](a: A, e: E)
              (implicit ev: InventoryListView Handles InventoryItemCreation) = {
  ev.handle(a, e)
  ...
}

Problem

If I define the following generic event handler ``` trait Handles[E <: Event] { def handle(event: E) } ``` with event type's like this ``` trait Event { } class InventoryItemDeactivated(val id: UUID) extends Event; class InventoryItemCreated(val id: UUID, val name: String) extends Event; ``` how do I then make a single class that implements event handlers for each of these events ?. I tried: ``` class InventoryListView extends Handles[InventoryItemCreated] with Handles[InventoryItemDeactivated] { def handle(event: InventoryItemCreated) = { } def handle(event: InventoryItemDeactivated) = { } } ``` but Scala complains that a trait cannot be inherited twice. I found this answer which hints at a solution, but it seams to require multiple classes (one for each handler). Is this really the only way or is there then some other Scala construct I can use to make a single class implement multiple generic event handlers (i.e. using case classes, manifests or some other fancy construct) ?.

Original source

Related problems