scala - 在一个特征中,引用一个扩展它的对象?

时间:2018-02-09 22:33:04

标签: scala

在数据科学中,构建竞争者模型是很常见的,这些模型扩展了像MaximumLikelihoodEstimation这样的常用功能。例如,您可能会遇到以下情况:

trait DataFrame
trait MaximumLikelihoodEstimation {
  case class MaximumLikelihoodFit(model: Model, params: Array[Double])
  def fit(data: DataFrame): MaximumLikelihoodFit = {
  val params: Array[Double] = ???
    // do math
    MaximumLikelihoodFit(
      model = this.getObject, // getObject doesn't exist... but something like this?
      params = params
    )
  }
}
trait Model // not important, implements things like pdf, cdf
object ModelA extends Model with MaximumLikelihoodEstimation
object ModelB extends Model with MaximumLikelihoodEstimation
object ModelC extends Model with MaximumLikelihoodEstimation

我应该更换this.getObject以获取正在调用fit的对象?例如,我希望ModelA.fit返回MaximumLikelihoodFit(ModelA, params)

1 个答案:

答案 0 :(得分:3)

您可能需要的内容称为Self-types。以下代码编译:

trait DataFrame
trait Model // not important, implements things like pdf, cdf

trait MaximumLikelihoodEstimation {
  self: Model => // this is the magic line!

  case class MaximumLikelihoodFit(model: Model, params: Array[Double])

  def fit(data: DataFrame): MaximumLikelihoodFit = {
    val params: Array[Double] = ???
    MaximumLikelihoodFit(
      model = this,
      params = params
    )
  }
}

object ModelA extends Model with MaximumLikelihoodEstimation
object ModelB extends Model with MaximumLikelihoodEstimation
object ModelC extends Model with MaximumLikelihoodEstimation

如果出于某种原因对您不起作用,可能您唯一的另一种选择是明确地引入getObject方法。恕我直言,导致最少打字的方式如下:

trait DataFrame

trait ModelProvider {
  val model:Model
}
trait Model extends ModelProvider {
  override val model: Model = this
}


trait MaximumLikelihoodEstimation {
  self: ModelProvider =>

  case class MaximumLikelihoodFit(model: Model, params: Array[Double])

  def fit(data: DataFrame): MaximumLikelihoodFit = {
    val params: Array[Double] = ???
    MaximumLikelihoodFit(
      model = this.model,
      params = params
    )
  }
}

object ModelA extends Model with MaximumLikelihoodEstimation
object ModelB extends Model with MaximumLikelihoodEstimation
object ModelC extends Model with MaximumLikelihoodEstimation