F-绑定多态性与抽象类型,而不是参数类型?(F-Bound Polymorphism with Ab

2019-09-01 06:46发布

我如何转换以下的F-绑定多态性用抽象类型的代码?

trait Organism[Self <: Organism[Self]] { self: Self =>
  def reproduceWith(org:Self):Boolean
}

class Amoeba extends Organism[Amoeba] {
  def reproduceWith(org:Amoeba) = //..code
}

Answer 1:

有多种方法可以做到这一点。 这是我喜欢的一种方式,类似于“参数化模块”的OCaml或阿格达。

当你定义你的Organism类型,你把它分解成一个抽象类Organism和特质OrganismOps 。 然后你在一个特质包裹这两种:

trait OrganismSystem {
    type Organism <: OrganismOps

    trait OrganismOps {
        def reproduceWith(org: Organism): Boolean
    }
}

因为它们被包裹在同一性状, OrganismOps可以看到Organism型。

现在,如果你想创建的这些东西一个具体的实例中,你可以这样做:

object MyOrganismSystem extends OrganismSystem {
    case class Organism(species: String) extends OrganismOps {
        def reproduceWith(org: Organism) = species == org.species
    }
}

如果你想定义的生物系统一般操作方法,你会带他们在OrganismSystem作为参数,或者等价地,在类,带有一个包装它们OrganismSystem作为参数:

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 Polymorphism with Abstract Types instead of Parameter Types?