user3593261
user3593261

Reputation: 568

Type mismatching when using type class

I defined a type class like this:

/** Type class */
trait Drivable[V <: Vehicle]{
    def drive(v:V)
}

It request a subtype of Vehicle as parameter of drive function. And now I'm trying to use this type class to the Vehicle itself.

/** ADT */
sealed trait Vehicle{
    def drive[V <: Vehicle](implicit d: Drivable[V]): Unit = d.drive(this)
}

the compiler complains:

Error:(15, 74) type mismatch;
 found   : Vehicle.this.type (with underlying type Vehicle)
 required: V
    def drive[V <: Vehicle](implicit d: Drivable[V]): Unit = d.drive(this)

It works if I force cast this to V

def drive[V <: Vehicle](implicit d: Drivable[V]): Unit = d.drive(this.asInstanceOf[V])

But I hate doing so. Or, it also works if I just put it in the case class:

final case class Car(name:String) extends Vehicle {
    def drive(implicit d: Drivable[Car]): Unit = d.drive(this)
}

But imaging I have many case classes, I have to repeat this in everyone.

What's the correct to use this type class in the base trait?

Upvotes: 0

Views: 91

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51648

Either make drive an extension method

sealed trait Vehicle

implicit class DrivableOps[V <: Vehicle](val vehicle: V) extends AnyVal {
  def drive(implicit d: Drivable[V]): Unit = d.drive(vehicle)
}

or make V a type member of the trait rather than type parameter of the method

sealed trait Vehicle { 
  type V >: this.type <: Vehicle
  def drive(implicit d: Drivable[V]): Unit = d.drive(this)
}

case class Bus() extends Vehicle {
  override type V = Bus
}
case class Car() extends Vehicle {
  override type V = Car
}

Type V can be generated automatically:

//libraryDependencies += "com.github.dmytromitin" %% "auxify-macros" % "0.8" 
import com.github.dmytromitin.auxify.macros.self 

@self sealed trait Vehicle { 
  def drive(implicit d: Drivable[Self]): Unit = d.drive(this) 
} 

@self case class Bus() extends Vehicle 
@self case class Car() extends Vehicle

Upvotes: 3

Related Questions