次の F バウンド ポリモーフィズムを抽象型を使用するコードに変換するにはどうすればよいですか?
trait Organism[Self <: Organism[Self]] { self: Self =>
def reproduceWith(org:Self):Boolean
}
class Amoeba extends Organism[Amoeba] {
def reproduceWith(org:Amoeba) = //..code
}
これにはさまざまな方法があります。これは、「パラメータ化されたモジュール」OCaml または Agda に似た、私が気に入っている方法の 1 つです。
型を定義するときはOrganism
、それを抽象型Organism
と traitに分割します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)
}
}