问题描述
如何将下面的F-Bound Polymorphism转换为使用抽象类型的代码?
trait Organism [Self< ;:生物体[Self]] {self:Self =>
def reproduceWith(org:Self):Boolean
}
class Amoeba extends Organism [Amoeba] {
def reproduceWith(org:Amoeba)= // ..代码
}
做这个。这是我喜欢的一种方式,类似于参数化模块
OCaml或Agda。
当您定义生物体
类型,将其分解为抽象类型生物体
和特征 OrganismOps
。然后你将这两个包装在一个特征中:
trait OrganismSystem {
type Organism< ;: OrganismOps
特性OrganismOps {
def reproduceWith(org:Organism):Boolean
}
}
由于它们被包装在同一个特征中,因此 OrganismOps
可以看到 Organism
类型。
现在,如果您想创建这些东西的具体实例,您可以这样做:
<$ p
> object MyOrganismSystem extends OrganismSystem {
case class Organism(species:String)extends OrganismOps {
def reproduceWith(org:Organism)= species == org.species $ b $如果你想定义在有机体系统上一般操作的方法,那么你可以使用一个或多个方法你可以让他们把一个 OrganismSystem
作为参数,或者等价地把它们包装在一个类中,该类需要一个 OrganismSystem
作为参数:
class UsesGenericOrganismSystem(system:OrganismSystem){
import system._
def allCompatible (有机体:Traversable [有机体]):布尔=
有机体.toSeq.combinations(2)forall {
案例Seq(o1,o2)=> o2.reproduceWith(o2)
}
}
How do I convert the following F-Bound Polymorphism to code using Abstract Types?
trait Organism[Self <: Organism[Self]] { self: Self =>
def reproduceWith(org:Self):Boolean
}
class Amoeba extends Organism[Amoeba] {
def reproduceWith(org:Amoeba) = //..code
}
解决方案
There are various ways to do this. Here is one way that I like, that is similar to "parameterized modules"OCaml or Agda.
When you define your
Organism
type, you split it into an abstract type Organism
and a trait OrganismOps
. Then you wrap both of these in a trait:
trait OrganismSystem {
type Organism <: OrganismOps
trait OrganismOps {
def reproduceWith(org: Organism): Boolean
}
}
Because they are wrapped in the same trait,
OrganismOps
can see the Organism
type.
Now if you want to create a concrete instance of these things, you would do this:
object MyOrganismSystem extends OrganismSystem {
case class Organism(species: String) extends OrganismOps {
def reproduceWith(org: Organism) = species == org.species
}
}
And if you want to define methods that operate generically on organism systems, you would have them take in an
OrganismSystem
as a parameter, or, equivalently, wrap them in a class that takes an OrganismSystem
as a parameter:
class UsesGenericOrganismSystem(system: OrganismSystem) {
import system._
def allCompatible(organisms: Traversable[Organism]): Boolean =
organisms.toSeq.combinations(2) forall {
case Seq(o1, o2) => o1.reproduceWith(o2)
}
}
这篇关于使用抽象类型而不是参数类型的F-bound多态性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!