I'm desperately trying to solve the following:
trait Access[Res[_]] { def access[C]: Res[C] }
trait CList[C1, A] extends Access[CList[_, A]] // ?!
def test[C1, C2, A](c: CList[C1, A]): CList[C2, A] = c.access[C2]
scalac just says: "error: illegal cyclic reference involving trait CList"
. how can I make this compile?
You might be interested in type lambdas. The partial application you used in your answer is actually implemented in scalaz. As the code tends to get less readable though, they started using type lambdas instead. The type in question could be written as
({type λ[α] = CList[α,A]})#λ
This works by creating a type projection on a parameterized type λ
inside a structural type thus capturing the outer type parameter (in this case A
).
The other problem concerning variance described in your answer could be solved by making the Res
parameter in Access
covariant.
After these changes your code should look like this:
trait Access[+Res[_]] { def access[C] : Res[C]}
trait CList[C, +A] extends Access[({type λ[α] = CList[α,A]})#λ]
googling for "partial type application" i found this solution posted by James Iry on the scala debate list ( http://scala-programming-language.1934581.n4.nabble.com/Partial-type-inference-td2007311.html ; adapted so the arg order is changed):
type Partial2[T[_,_], B] = {
type Apply[A] = T[A,B]
}
trait CList[C1, A] extends Access[Partial2[CList, A]#Apply]
cheese louise, is this really the only way to do that in scala in 2011 ?!!
EDIT:
This fails with covariance in A
:,-(
trait Access[Res[_]] { def access[C]: Res[C] }
type Partial2[T[_,_], B] = {
type Apply[A] = T[A,B]
}
trait CList[C1, +A] extends Access[Partial2[CList, A]#Apply]
"covariant type A occurs in invariant position"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With