score:1

Accepted answer

i don't have an answer per say, but here are some thoughts. first of all, i've simplified and clarified your code example to minimize down to the problem:

trait effect[a]
trait actionresult[+m, +a]
trait modelupdated[+m] extends actionresult[m, nothing]
trait haseffect[+m, +a] extends actionresult[m, a]

case class modelupdateeffect[m, a](newmodel: m, effect: effect[a]) extends modelupdated[m] with haseffect[m, a]

object main {
  def foo[m, a]: actionresult[m, a] = ???
  def dispatch[m, a] = {
    foo[m, a] match {
      case modelupdateeffect(newmodel, effect) =>
        val e: effect[a] = effect // does not compile                                                              
        false
      case _ => true
    }
  }
}

let's note the error message we get for that line:

type mismatch;
 found   : effect[any]
 required: effect[a]
note: any >: a, but trait effect is invariant in type a.

it's kind of strange the compiler decides that effect has type effect[any]. but let's see what happens if we replace this definition:

case class modelupdateeffect[m, a](newmodel: m, effect: effect[a]) extends modelupdated[m] with haseffect[m, a]

with this:

case class modelupdateeffect[m, a](newmodel: m, effect: effect[a]) extends haseffect[m, a]

now we get a different error message:

type mismatch;
 found   : effect[?a1] where type ?a1 <: a (this is a gadt skolem)
 required: effect[a]
note: ?a1 <: a, but trait effect is invariant in type a.

in this case, the types really don't match up right. let's walk through it. we know from outside the case statement that we have an actionresult[m, a]. but because of the covariance on the type param a, that actionresult[m, a] may well be an actionresult[m, b] forsome { type b <: a }. in other words, there may be some type b that is a sub-type of a, and foo[m, a] might return an actionresult[m, b]. in which case, effect would be an effect[b], and because the type parameter for effect is invariant, this type is not compatible with effect[a].


Related Query

More Query from same tag