我试图在trait中使用covariant类型参数来构造一个case类,如下所示:
trait MyTrait[+T] {
private case class MyClass(c: T)
}
Run Code Online (Sandbox Code Playgroud)
编译说:
error: covariant type T occurs in contravariant position in type T of value c
Run Code Online (Sandbox Code Playgroud)
然后我尝试了以下但它也没有用:
trait MyTrait[+T] {
private case class MyClass[U <: T](c: U)
}
Run Code Online (Sandbox Code Playgroud)
这次的错误是:
error: covariant type T occurs in contravariant position in type >: Nothing <: T of type U
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么T在这里处于协变位置并建议解决这个问题吗?谢谢!
我有一点Aux模式的感觉(在无形和其他地方使用),其中一个类型成员被提取到一个类型参数,我知道这是一个解决方法,相同的参数列表中的参数不能依赖在彼此 - 但我一般不清楚它用于什么以及它解决了什么问题.
例如,我目前正在试图弄清楚如何保存和使用whitebox宏返回的更具体的类型 - 这是Aux的用例吗?
有简单的描述吗?
我有一个与此非常类似的问题:Scala更高的kinded类型方差
然而,这有点不同,嗯,它不编译(scala 2.11.8).
基本思想是采用一系列"事物".如果数组为空,返回某种类型的默认值(例如Boolean,Option,List[Int]),否则就阵列上的工作,并产生一个结果.结果和默认值具有相同的类型.
我遇到的挑战是让这个结果适用于广泛的结果类型.
这是一个人为的例子:
trait NullGuard[F[_]] {
def nullGuard[A, B](arr: Array[A], default: F[B])(expr: => F[B]): F[B] =
if (arr == null || arr.length == 0) default else expr
}
Run Code Online (Sandbox Code Playgroud)
让我们创建一个返回Option的实现:
implicit def optionNullGuard[F[X] <: Option[X]]: NullGuard[F] = new NullGuard[F]() {}
Run Code Online (Sandbox Code Playgroud)
以上编译,但以下尝试使用上述类型不会:
def returnsOption[F[_], A, B](arr: Array[A])(implicit ng: NullGuard[F]): Option[B] = {
ng.nullGuard(arr, None) {
// sample work
if (arr.length % 2 == 0) Option(1) else None
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译错误:
type mismatch; …Run Code Online (Sandbox Code Playgroud)