当类型是协变时,为什么我们不能提供隐式类型类?
Why can't we provide implicit typeclass when a type is covariant?
我在设计我的代数数据类型时遇到了无法提供隐式类型类的问题。这是我拥有的:
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()
我让它协变是为了能够 return Halt extends Stream[Nothing, Nothing]
无需强制转换,但我需要 Monad[F]
类型类以便将其操作用于上下文 F[_]
假如。在这种情况下有什么解决方案?
只有当 Monad
是 contra 变体时才会编译。否则你有:
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]
的子类型。
What would be a solution in this case?
不是这样定义run
?通常,因为 scalaz 和 cats 决定使它们的类型类不变,所以当您尝试在 co/contravariant 类型中使用它们时,您会 运行 遇到麻烦。
我在设计我的代数数据类型时遇到了无法提供隐式类型类的问题。这是我拥有的:
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()
我让它协变是为了能够 return Halt extends Stream[Nothing, Nothing]
无需强制转换,但我需要 Monad[F]
类型类以便将其操作用于上下文 F[_]
假如。在这种情况下有什么解决方案?
只有当 Monad
是 contra 变体时才会编译。否则你有:
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]
的子类型。
What would be a solution in this case?
不是这样定义run
?通常,因为 scalaz 和 cats 决定使它们的类型类不变,所以当您尝试在 co/contravariant 类型中使用它们时,您会 运行 遇到麻烦。