Skip to content

Instantly share code, notes, and snippets.

@debasishg
Last active February 5, 2016 21:24
Show Gist options
  • Select an option

  • Save debasishg/70bd1d1a2d0f0e4b7828 to your computer and use it in GitHub Desktop.

Select an option

Save debasishg/70bd1d1a2d0f0e4b7828 to your computer and use it in GitHub Desktop.
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> import scala.language.higherKinds
import scala.language.higherKinds
scala> trait Foo[M[+_]] {
| implicit def M: Monad[M]
| def foo(s: String): M[Int]
| }
defined trait Foo
scala> type ErrorOr[+A] = String \/ A
defined type alias ErrorOr
scala> class Bar extends Foo[ErrorOr] {
| val M: Monad[ErrorOr] = Monad[ErrorOr]
| def foo(s: String): ErrorOr[Int] = s.length.right
| }
defined class Bar
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
// I cannot be covariant here, since EitherT is invariant in its parameters
scala> type Valid[A] = EitherT[Future, NonEmptyList[String], A]
defined type alias Valid
scala> class Baz extends Foo[Valid] {
| val M: Monad[Valid] = Monad[Valid]
| def foo(s: String): Valid[Int] = ???
| }
<console>:18: error: kinds of the type arguments (Valid) do not conform to the expected kinds of the type parameters (type M) in trait Foo.
Valid's type parameters do not match type M's expected parameters:
type A is invariant, but type _ is declared covariant
class Baz extends Foo[Valid] {
@S11001001

Copy link
Copy Markdown

Need foo's M have +?

A covariant type constructor conforms to an invariant one, in accordance with SI-2066, so it is possible to

trait Foo[M[_]]
trait Bar[M[+_]] extends Foo[M]

Unfortunately, doing this right for transformers (and presumably there's another parameter you're using inside the Ms, hence the desire for variance) would need variance variables, not just variance conformance, e.g.

final case class EitherT[~a, a~E, M[a~_], a~A]

Where a prefix ~ indicates variance-variable binding, suffix usage. And it's yet more complicated when the variance of the A position isn't merely always equal to the M constructor's variance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment