我是斯卡拉新手...所以假设无知。
因此,如果我看一下<:的定义<</p>
sealed abstract class <:<[-From, +To] extends (From => To)
implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x}
这用于定义 A 型是 B 的亚型的证据。
A <: B
。但是,如果我想有证据呢?
福拉尔·A[T] <: B[T]
?
还行。。。。所以我尝试遵循相同的食谱
abstract class Foo[-A[_],+B[_]] { def apply[C](x : A[C]) : B[C] }
implicit def conforms[A[_]] : Foo[A,A] = new Foo[A,A] { def apply[C](x : A[C]) : A[C] = x }
我可以使用此约束手动应用转换,但我无法让编译器隐式"应用"它。(因为它不扩展 A=>B?
例如,如果我定义;
abstract class FooInt[-A[_],+B[_]] extends (A[Int] => B[Int])
implicit def conformsInt[A[Int]] : FooInt[A,A] = new FooInt[A,A] { def apply(x : A[Int]) : A[Int] = x }
则编译器将自动将转换应用于类型 A[Int] 的值
我只想将其推广到 A[T]
思潮?
sealed abstract class <:<
- 这告诉你你不能构建"新证据"。您必须依赖编译器确认两个现有类型确实满足现有证据。这应该已经适用于所有类型,如果没有,您可以尝试证明错误的东西。
你说你想要证明A[T] <: B[T] forAll { type T }
.这将取决于 A 和 B 的类型参数的方差。如果要忽略该参数,则只能A[_] <:< B[_]
请求证据。例如
trait Animal; trait Cat extends Animal
trait Foo[A]
trait Bar[A] extends Foo[A]
implicitly[Bar[Cat] <:< Foo[Cat]] // ok, A is fixed
implicitly[Bar[Cat] <:< Foo[Animal]] // not possible
implicitly[Bar[Animal] <:< Foo[Cat]] // not possible
implicitly[Bar[_] <:< Foo[_]] // ok, we forget about A
如果您有差异,则可以保留 A:
trait Breeds[+A] // covariant, can "produce" A
trait Feeds [-A] // contravariant, can "consume" A
class Baz[A] extends Breeds[A] with Feeds[A]
implicitly[Baz[Cat] <:< Feeds[Animal]] // nope
implicitly[Baz[Animal] <:< Feeds[Cat]] // ok
implicitly[Baz[Cat] <:< Breeds[Animal]] // ok
implicitly[Baz[Animal] <:< Breeds[Cat]] // nope