Search code examples
scalacovariancescalaz

Can WriterT be made covariance? Can WriterT[F[_], W, A] be declared with +A instead?


I have code like:

type StringValidation[+A] = Validation[String, A]
type WriterValidation[A] = WriterT[StringValidation, String, A]
type Result[A] = WriterValidation[A]

private def someResult: Result[Int]
def implementTrait: Result[Any] = someResult    // type mismatch

it gives type mismatch, found Result[Int], required Result[Any], but if I change it to:

type WriterValidation[+A] = WriterT[StringValidation, String, A]

it gives "covariant type A occurs in invariant position in WriterT..."

it occurs to me that the operation should be Okay in concept, Validation can be covariance, why WriterT could not (or is not) decared WriterT[F[_], W, +A] (or even with +W)?

I'm using scalaz7 snapshot, but I see that the declaration of WriterT in 6.0.4 is the same.


Solved.
it turns out that I used the wrong version, what I used was "org.scalaz" %% "scalaz-core" % "7.0-SNAPSHOT", once I switched to "org.scalaz" % "scalaz-core_2.9.2" % "7.0.0-M2" it's ok


Solution

  • Not sure about your situation, but scalaz-seven tree (and also the M2 release) has covariant type args.

        sealed trait WriterT[F[+_], +W, +A] { ...
    

    Also the following works:

        scala> type SV[+A] = Validation[String, A]
    defined type alias SV
    
    scala> type WV[+A] = WriterT[SV, String, A]
    defined type alias WV
    
    scala> type Result[+A] = WV[A]
    defined type alias Result
    
    scala> def someResult: Result[Int] = ???
    someResult: Result[Int]
    
    scala> def implementTrait: Result[Any] = someResult
    implementTrait: Result[Any]