【问题标题】:Why is f-bounded polymorphism im Scala commonly implemented with an upper type bound as well as a self type为什么 Scala 中的 f 有界多态性通常使用上限类型和 self 类型来实现
【发布时间】:2021-05-24 21:43:51
【问题描述】:

为什么 Scala 中的 f 有界多态性通常使用上限类型 以及 类似的 self 类型实现

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

而不仅仅是只是一个像

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

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

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

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

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

【问题讨论】:

    标签: scala f-bounded-polymorphism


    【解决方案1】:

    所以,trait MyTrait[A &lt;: MyTrait[A]] { self: A =&gt; ... } 的想法是强制 A 成为当前实现的类型。

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

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

    甚至只是class Bat extends Foo[Any]

    【讨论】:

    • 我猜trait Bar with Foo 应该是trait Bar extends Foo[Bar]?整个构造(包括您对Baz 的定义)也可以使用 上限,并且是Scala 中f 有界多态性的表达能力的已知限制。 Any 的例子似乎确实是一个显着的区别。我也不明白你所说的“Foo 不能用它的类型参数做很多事情”是什么意思。你有没有一个例子Foo 可以用它的类型参数做没有它不能做的上限?
    • @mrArkwright 没有上限,Foo 的参数必须是Foo 的子类,而Bar 不是,所以Foo[Bar] 是不可能的。
    • @mrArkwright 回复。 “Foo 可以用上限做什么”......好吧,我不知道......def foo: A = this
    • 对不起,你误会了。我刚刚编译了这三行代码 with 上限(以及trait Bar extends Foo[Bar]。你能确认一下,这就是你的意思吗?或者最好相应地编辑你的答案。)请继续自己试试吧。
    • def foo: A = this 也可以没有上限。所以这没什么区别。
    猜你喜欢
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 2018-05-20
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-03
    相关资源
    最近更新 更多