Issue with using EitherT

50 views
Skip to first unread message

ace_coder

unread,
Oct 23, 2016, 11:09:16 PM10/23/16
to scalaz
How do I constrain a covariant type to invariant type so that I can pass it as a type parameter to EitherT?

Something of the form: 
 
   type  Method[+T] = EitherT[F, Int, T]       // Error: Usage of covariant type in invariant position.

Is there a lambda expression that would allow me to further constrain T before passing it to EitherT?

Thank you for your time and consideration!

Stephen Compall

unread,
Oct 24, 2016, 6:47:10 AM10/24/16
to sca...@googlegroups.com, ace_coder
On October 23, 2016 11:09:16 PM EDT, ace_coder <ama...@gmail.com> wrote:
>How do I constrain a covariant type to invariant type so that I can
>pass it
>as a type parameter to EitherT?
>
>Something of the form:
>
>type Method[+T] = EitherT[F, Int, T] // Error: Usage of
>covariant
>type in invariant position.

Method can only be defined as Method[T] here. Technically, EitherT[F, Int, _ <: T] has the semantics you want and T in covariant position (one implication of the covariance of any Cv[+A] is that for all T, Cv[T] = Cv[_ <: T]), but scalac isn't great at inferring its usage, never mind implicit conversions from it.

Covariant type constructors widen to invariant, but not vice versa, and the invariance of EitherT is deliberate; see https://failex.blogspot.com/2016/09/the-missing-diamond-of-scala-variance.html for explanation.




--
Stephen Compall
If anyone in the MSA is online, you should watch this flythrough.

ace_coder

unread,
Oct 25, 2016, 3:32:00 AM10/25/16
to scalaz, ama...@gmail.com
I could possibly create a wrapper class/type that coerced the type to be invariant, for example if I had a wrapper class C[+T].

C[+T](...) {
    type B <: T

    val innerObj: EitherT[F, A, B]
}

Something like the above could work, right? But I was hoping for a cleaner solution -- one that didn't require an entirely new class.

Stephen Compall

unread,
Nov 12, 2016, 1:47:57 PM11/12/16
to sca...@googlegroups.com, ace_coder
On October 25, 2016 3:32:00 AM EDT, ace_coder <ama...@gmail.com> wrote:
>C[+T](...) {
> type B <: T
>
> val innerObj: EitherT[F, A, B]
>}
>
>Something like the above could work, right? But I was hoping for a
>cleaner
>solution -- one that didn't require an entirely new class.

type Method[+T] = EitherT[F, Int, _ <: T]

should compile.
Reply all
Reply to author
Forward
0 new messages