I have a set of classes of models, and a set of algorithms that can be run on the models. Not all classes of models can perform all algorithms. I want model classes to be able to declare what algorithms they can perform. The algorithms a model can perform may depend on its arguments.
Example: Say I have two algorithms, MCMC, and Importance, represented as traits:
trait MCMC extends Model {
def propose...
}
trait Importance extends Model {
def forward...
}
I have a model class Normal, which takes a mean argument, which is itself a Model. Now, if mean implements MCMC, I want Normal to implement MCMC, and if mean implements Importance, I want Normal to implement Importance.
I can write: class Normal(mean: Model) extends Model { // some common stuff goes here }
class NormalMCMC(mean: MCMC) extends Normal(mean) with MCMC {
def propose...implementation goes here
}
class NormalImportance(mean: Importance) extends Normal(mean) with Importance {
def forward...implementation goes here
}
I can create factory methods that make sure the right kind of Normal gets created with a given mean. But the obvious question is, what if mean implements both MCMC and Importance? Then I want Normal to implement both of them too. But I don't want to create a new class that reimplements propose and forward. If NormalMCMC and NormalImportance didn't take arguments, I could make them traits and mix them in. But here I want the mixing in to depend on the type of the argument. Is there a good solution?