F-Bound Polymorphism with Abstract Types instead of Parameter Types?

后端 未结 1 1818
灰色年华
灰色年华 2021-01-06 07:01

How do I convert the following F-Bound Polymorphism to code using Abstract Types?

trait Organism[Self <: Organism[Self]] { self: Self =>
  def reproduc         


        
相关标签:
1条回答
  • 2021-01-06 07:41

    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)
            }
    }
    
    0 讨论(0)
提交回复
热议问题