trait KList[+M[_]] {
type Transformed[N[_]] <: KList[N]
type Appended[N[X] >: M[X], T <: KList[N]] <: KList[N]
}
case class KCons[+M[_], +T <: KList[M]](tail: T) extends KList[M] {
type Transformed[N[_]] = KCons[N, T#Transformed[N]]
type Appended[N[X] >: M[X], L <: KList[N]] = KCons[N, T#Appended[N, L]]
}
Error messages:
<console>:20: error: covariant type T occurs in invariant position in
type [N[_]]KCons[N,T#Transformed[N]] of type Transformed
type Transformed[N[_]] = KCons[N, T#Transformed[N]]
<console>:21: error: covariant type T occurs in invariant position in
type [N[X] >: M[X], L <: KList[N]]KCons[N,T#Appended[N,L]] of type Appended
type Appended[N[X] >: M[X], L <: KList[N]] = KCons[N,
T#Appended[N, L]]
<console>:21: error: covariant type M occurs in invariant position in
type [X]>: M[X] <: Any of type N
type Appended[N[X] >: M[X], L <: KList[N]] = KCons[N,
T#Appended[N, L]]
The first two messages can be avoided when using "tail." instead of
"T#". I couldn't find any fix for the third one, though. I don't even
know what "in type [X]>: M[X] <: Any of type N" is supposed to mean.
thanks for your remarks.
> trait KList[+M[_]] {
> type Transformed[N[_]] <: KList[N]
> }
>
> case class KCons[A, +M[_], T <: KList[M]](head:M[A], tail: T) extends
> KList[M] {
> type Transformed[N[_]] = KCons[A, N, T#Transformed[N]]
> }
Indeed. This compiles because T is not covariant anymore. Unfortunately,
I rely on a covariant T at some places.
> I'm not sure what appended is supposed to do [...]
`KList[M]#Appended[N, T]` should be the type level computation of the
result type when appending a `KList[N]` at the end of a `KList[M]`
(where `N >: M`).
There is always the possibility to write those operations using external
proofs, but this is rather tedious which is why I want then to be
included in the class itself.
Regards
Lars
That's strange.
By the way, I tried implementing `append` by using implicit conversion,
but everything bites me again.
scala> class Foo[M[_]]
defined trait Foo
scala> implicit def enrichFoo[M[_], T <: Foo[M]](foo: T) = new { def
flyingDog = "swoosh" }
enrichFoo: [M[_], T <: Foo[M]](foo: T)java.lang.Object{def flyingDog:
java.lang.String}
scala> new Foo[Option]
res4: Foo[Option] = Foo@4f1d0f91
scala> res4.flyingDog
<console>:14: error: value flyingDog is not a member of Foo[Option]
res4.flyingDog
^
scala> enrichFoo(res4).flyingDog
<console>:14: error: inferred type arguments [Nothing,Foo[Option]] do
not conform to method enrichFoo's type parameter bounds [M[_],T <: Foo[M]]
enrichFoo(res4).flyingDog
import scala.annotation.unchecked._
trait KList[@uncheckedVariance +M[_]] {
type Appended[N[X] >: M[X], T <: KList[N]] <: KList[N]
}
case class KCons[@uncheckedVariance +M[_], +T <: KList[M]](tail: T)
extends KList[M] {
type Appended[N[X] >: M[X], L <: KList[N]] =
KCons[N, tail.Appended[N, L]]
}
This still gives me "covariant type M occurs in invariant position".