Scala 为什么可以';当类型是协变的时,我们是否提供隐式类型类?
我在设计代数数据类型时遇到了一个无法提供隐式类型类的问题。以下是我所拥有的:Scala 为什么可以';当类型是协变的时,我们是否提供隐式类型类?,scala,functional-programming,typeclass,scalaz,scala-cats,Scala,Functional Programming,Typeclass,Scalaz,Scala Cats,我在设计代数数据类型时遇到了一个无法提供隐式类型类的问题。以下是我所拥有的: sealed abstract class Stream[+F[_], +T] { def run()(implicit M: Monad[F]): F[Unit] = Stream.run(this) } object Stream{ final case object Halt extends Stream[Nothing, Nothing] private def run[F[_], T](stre
sealed abstract class Stream[+F[_], +T] {
def run()(implicit M: Monad[F]): F[Unit] = Stream.run(this)
}
object Stream{
final case object Halt extends Stream[Nothing, Nothing]
private def run[F[_], T](stream: Stream[F, T])(implicit M: Monad[F]): F[Unit] = stream match {
case Halt => M.pure()
}
}
我得到了编译错误
Error:(10, 22) covariant type F occurs in invariant position in type
Monad[F] of value M def run()(implicit M: Monad[F]): F[Unit] = M.pure()
我使其协变,以便能够在不强制转换的情况下返回
Halt extends Stream[Nothing,Nothing]
,但我需要Monad[F]
typeclass,以便将其操作用于提供的上下文F[\u]
。在这种情况下,解决方案是什么?只有当Monad
是反向变量时,才会编译。否则,您必须:
val stream: Stream[Nothing, Nothing] = Halt
val stream1: Stream[Maybe, Int] = stream // by covariance
val x = stream1.run()(implicitly[Monad[Maybe]])
但是Halt.run
只接受Monad[Nothing]
,因此Monad[Maybe]
必须是Monad[Nothing]
的子类型
在这种情况下,解决方案是什么
不这样定义运行?一般来说,因为scalaz和cats决定使它们的类型类保持不变,所以在尝试将它们用于协变/逆变类型时会遇到麻烦