In lieu of trait arguments

2019-06-02 22:15发布

问题:

Here's what I want to write:

val alg10 = new GeneticAlgorithm[FlatDesign]
  with PhenotypeSize(10)
  with FlatDesignMutator
  with ChildrenReplaceParents(numChildren=2)
  with TargetFitnessFunction(targetPhenotype)
  with PopulationSize(40)
  with RunLength(numGenerations=100)

In other words, there are lots of constraints and parameters I'd like to set. For example, PhenotypeSize(10) has implications for the mutator and the fitness function. Abstract types ought to make it easy to implement/enforce all of those consistency constraints. Of course, traits can't take parameters, so this code won't work.

I love how composing traits lets you mix and match whatever functionality you need. The code above is so readable! With code like that, I could easily write a loop to try out the Cartesian product of lots and lots of variations to the algorithm.

I'm stuck, though, on finding a clean way to supply the parameters for those traits. Any suggestions?

回答1:

Early definitions are described in Programming in Scala as "pre-initialized fields" or 5.1.6 of the spec and have the semantics you'd expect from trait parameters, namely, they are available in constructors.

val alg10 = new { val size = 10 } with GeneticAlgorithm[FlatDesign]
  with PhenotypeSize { val size: Int ; val psize = 2 * size }

This question must be a duplicate.



回答2:

This may be what you are doing already, but just in case, if you define your traits like this:

trait PhenotypeSize {
    val size: Int
    ...
}
trait FlatDesignMutator { ... }
trait ChildrenReplaceParents {
    val numChildren: Int
    ...
}
...

Then your class will look like:

class GeneticAlgorithm[T]
    extends PhenotypeSize
    with FlatDesignMutator
    with ChildrenReplaceParents
    with ... {
    override val size: Int = 2
    override val numChildren: Int = 10
    ...
}

The compiler will check that you have given proper definitions for the members size, numChildren, and so on in your GeneticAlgorithm class implementation. This sounds reasonably nice and concise to me.