使用抽象类型而不是参数类型的F-bound多态性? [英] F-Bound Polymorphism with Abstract Types instead of Parameter Types?

查看:202
本文介绍了使用抽象类型而不是参数类型的F-bound多态性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将下面的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多态性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆