Question

Suppose I'm trying to represent, say, the domain of boolean logic (ignoring reduction for now). So I'll have in my store instances of Bools, or Ands and Ors or Nots etc. However, whilst I'll have concrete representations for these things, in many cases all I'll care about is that something can, say, be viewed as a Bool, or as a combination of two Bools (this doesn't quite make sense here, but the bigger example is some kind of heterogenous data store where I might request, say, all things that might have a colour). There are multiple potential hierarchies, so subclassing doesn't really cut it, and since I want to avoid explicit conversion, typeclasses seem to be the way to go. So I have something like this:

trait Delegated[-B, +A] {
  def bind(b : B) : A
}

trait Thing[A <: Thing[A]] {
  type Class[B] = Delegated[B,A]
}


trait BoolLike extends Thing[BoolLike] {
  def value : Boolean
}
class Bool(val value : Boolean) extends BoolLike

Now, however, to avoid repeating myself, I would like to specify that, for any Thing, a subclass will satisfy Thing#Class. So my attempt at this was the following:

implicit def SubclassIsClass[A <: Thing[A], B <: A] : A#Class[B] = new A#Class[B] { 
  def bind(b : B) = b
}

However, if I do

implicitly[BoolLike#Class[Bool]]

I get no evidence, yet I can quite happily call SubclassIsClass[BoolLike, Bool] and get an appropriate Delegate. Should this be implicitly inferrable?

Was it helpful?

Solution

Solved it - if I change

trait Delegated[-B, +A]

to

trait Delegated[B,A]

then this works. Given that the annotations were left over from a different way of doing things, this seems like a fine solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top