Reputation: 1802
I have:
sealed trait Par[A]{def foo = ???}
case class Unit[A](v: () => A) extends Par[A]
case class Map2[L, R, A](parLeft: Par[L],
parRight: Par[R],
map: (L, R) => A) extends Par[A]
my problem is that when I pattern match on p:Par[A]
to do something like this:
def getSequentially: A = this match {
case Par.Unit(f) => f()
case Par.Map2(a, b, f) => f(a.getSequentially, b.getSequentially)
}
L
and R
are inferred to be Any
in Intellij's type inspector and getSequentially
calls are highlighted in red, warning: type mismatch, expected Nothing, actual Any
, since f
is expected to be of type: (Nothing, Nothing) => A
. Although it actually runs and compiles.
I think I understand what the problem is and I should be able to solve it with existential types in the definition of Map2
. Only problem is that the map
parameter has a dependent type, so I don't know how to do that. Maybe I should do a variation of the AUX pattern?
My question is, firstly why it compiles and secondly, if there is a way of restructuring the type dependency so that it no longer issues a warning.
Upvotes: 1
Views: 107
Reputation: 51723
If you want to have existentials you can use typed patterns:
sealed trait Par[A]{
def getSequentially: A = this match {
case x: Par.Unit[A] => x.v()
case x: Par.Map2[_, _, A] => x.map(x.parLeft.getSequentially, x.parRight.getSequentially)
}
}
object Par {
case class Unit[A](v: () => A) extends Par[A]
case class Map2[L, R, A](parLeft: Par[L],
parRight: Par[R],
map: (L, R) => A) extends Par[A]
}
IntelliJ seems not to highlight this.
Upvotes: 2