Scala中具有抽象类型的F界多态

劳伦斯·瓦格菲尔德

我已经阅读了几篇文章,这些文章表达了应使用抽象类型在Scala中实现f界多态性。这主要是为了减轻类型推断问题,而且还消除了在定义递归类型时类型参数似乎引入的二次增长。

这些定义如下:

trait EventSourced[E] {
  self =>

  type FBound <: EventSourced[E] { type FBound <: self.FBound }

  def apply(event: E): FBound
}

但是,这似乎引入了两个问题:

1)每次用户想要引用此类型的对象时,他们还必须引用FBoundtype参数。这感觉像代码气味:

def mapToSomething[ES <: EventSourced[E], E](eventSourced: ES#FBound): Something[ES, E] = ...

2)编译器现在无法推断上述方法的类型参数,并显示以下消息:

Type mismatch, expected: NotInferredES#FBound, actual: MyImpl#FBound

有没有人在他们的解决方案中成功使用f界多态性实现,从而使编译器仍然能够推断类型?

劳伦斯·瓦格菲尔德

从那以后,我意识到在大多数情况下应该避免f界多态性,或者更确切地说,通常应该选择一种替代设计。要了解如何避免它,我们首先需要知道是什么使我们需要它:

当一个类型期望在派生类型中引入重要的接口更改时,就会发生F界多态性

通过组成预期的更改区域而不是尝试通过继承来支持它们,可以避免这种情况这实际上可以归结为四种设计模式的组合:

赞成“对象组成”胜于“类继承”

-(四人帮,1995)

例如:

trait Vehicle[V <: Vehicle[V, W], W] {
    def replaceWheels(wheels: W): V
}

变成:

trait Vehicle[T, W] {
    val vehicleType: T
    def replaceWheels(wheels: W): Vehicle[T, W]
}

这里,“预期的改变”是车辆类型(例如BikeCarLorry)。前面的示例假定将通过继承来添加,这需要一个f边界类型,该类型使对W使用Vehicle的任何函数无法进行推断使用合成的新方法不会出现此问题。

参见:https : //github.com/ljwagerfield/scala-type-in​​ference/blob/master/README.md#avoiding-f-bounded-polymorphism

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用具有抽象类型的 Scala 数组

F界多态Java中的返回类型

具有很多DI参数的多态抽象类

Scala类型类可以具有抽象类型成员吗?

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

为具有TypeScript中类型变量的抽象类的派生类分配通用类型

Scala 中的抽象类型、变量和类型类

Scala抽象类型成员

如何在Jackson中对具有抽象类型的引用进行反序列化JSON

抽象类是否可以具有其他抽象类的返回类型的方法?

具有多个参数类型的抽象类方法

F界多态性中子类型的Scala重写类型参数

F界多态性的解析类型

F界多态类型和非泛型子类型的现有类型?

当您具有抽象类型的数组时,如何访问不在抽象类型上的派生类型成员

R中的抽象类型

Scala抽象类中的私有构造函数?

抽象类中的 ModelAttribute 具有来自子类的值

在Kotlin中创建具有通用Type的抽象类

phpunit中具有受保护方法的抽象类

C ++ / Qt中具有泛型的抽象类

什么是TypeScript中的F界多态

如何在可拆分的Android Studio Java中传递具有抽象类类型作为参数的类

在基类构造函数中使用抽象类作为参数,以在派生类中具有更多特定类型

Scala:抽象类型与泛型

将抽象类类型类型转换为具有整数成员的结构类型

具有Ordering和ClassTag的Scala多态类型签名

具有隐式类型标记的Scala模拟多态方法

如何在Scala中反映与抽象类型的类型参数相对应的具体类型?