为什么 f 有界多态性 im Scala 通常使用类型上限和自类型实现

问题描述

为什么 Scala 中的 f-bounded 多态性通常使用上限类型以及这样的 self 类型来实现

trait MyTrait[A <: MyTrait[A]] { self: A =>
  …
}

而不是简单地只是

这样的自我类型
trait MyTrait[A] { self: A =>
  …
}

一个例子中的上界似乎是不必要的。至少我找不到使用它的任何好处。我在这里忽略了什么吗?然而,类型边界确实阻碍了像

这样的用法
def func[A](implicit ev: A <:< MyTrait[A]) = ???

(当然,在这个简单而人为的示例中,func[A <: MyTrait[A]] 可以解决问题,但在更复杂的设置中可能无法实现)

我发现 f-bounded polymorphism with 在多个库中实现了一个类型绑定,甚至在一篇关于该主题的介绍性博客文章 (https://tpolecat.github.io/2015/04/29/f-bounds.html) 中,我想知道是否会更好一般省略类型绑定。

解决方法

因此,trait MyTrait[A <: MyTrait[A]] { self: A => ... } 的想法是强制 A 成为当前实现的类型。

如果省略上界,那么除了 Foo 不能对它的类型参数做很多事情(它对它的成员一无所知)之外,你还可以做这样的事情,这不是非常有用。

   trait Foo[A] { self: A => }
   trait Bar 
   class Baz extends Foo[Bar] with Bar

甚至只是class Bat extends Foo[Any]