1

Given type erasure, what is the most efficient and elegant way to solve the following overloading definition:

trait Signal

trait Step[T] {
  def ar(implicit ev: T <:< Boolean): Signal
  def ar(implicit ev: T <:< Float  ): Signal
}

without using different names for Boolean and Float parametrisation? Ideally it would be T <:< Boolean union Float but that does not exist... Can I do without an extra implicit indirection?

0__
  • 66,707
  • 21
  • 171
  • 266
  • The `Boolean union Float` would not help in the actual implementation, though, because that would need to figure out how to convert `T` into another type (e.g. `Float`), thus requiring overloading. – 0__ Sep 05 '12 at 11:09
  • See [Does Scala have “type disjunction” (union types)?](http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types) – Aaron Novstrup Sep 05 '12 at 22:54

1 Answers1

4

The extra indirection would be this:

object Step {
  sealed trait SignalSource[T] { def toFloat(t: T): Float }
  implicit object BooleanSource extends SignalSource[Boolean] {
    def toFloat(t: Boolean) = if (t) 1f else 0f
  }
  implicit object FloatSource extends SignalSource[Float] {
    def toFloat(t: Float) = t
  }
}
trait Step[T] {
  def ar(implicit ev: Step.SignalSource[T]) : Signal
}
0__
  • 66,707
  • 21
  • 171
  • 266
  • Someone has called this [magnet pattern](http://spray.io/blog/2012-12-13-the-magnet-pattern/) – 0__ Dec 15 '12 at 18:51