隐式转换高阶类型

  • 本文关键字:类型 高阶 转换 scala
  • 更新时间 :
  • 英文 :


我是斯卡拉新手...所以假设无知。

因此,如果我看一下<:的定义<</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

最新更新