title: Implementing a Cake Pattern with implicit functionality
body: <p>I have a scenario where I want to implement a variant of a Cake Pattern, but adding implicit functionality to a class (a Spark DataFrame). </p>
  
  <p>So, basically, I want to be able to run a code like the following:</p>
  
  
  
  <pre class="lang-scala prettyprint-override"><code>trait Transformer {
    this: ColumnAdder =&gt;
  
    def transform(input: DataFrame): DataFrame = {
      input.addColumn("newCol")
    }
  }
  
  val input = sqlContext.range(0, 5)
  val transformer = new Transformer with StringColumnAdder
  val output = transformer.transform(input)
  output.show
  </code></pre>
  
  <p>And find a result like the following:</p>
  
  <pre class="lang-scala prettyprint-override"><code>+---+------+
  | id|newCol|
  +---+------+
  |  0|newCol|
  |  1|newCol|
  |  2|newCol|
  |  3|newCol|
  |  4|newCol|
  +---+------+
  </code></pre>
  
  <p>My first idea was to define the implicit classes only in the base traits:</p>
  
  <pre class="lang-scala prettyprint-override"><code>trait ColumnAdder {
    protected def _addColumn(df: DataFrame, colName: String): DataFrame
  
    implicit class ColumnAdderRichDataFrame(df: DataFrame) {
      def addColumn(colName: String): DataFrame = _addColumn(df, colName)
    }
  }
  
  trait StringColumnAdder extends ColumnAdder {
    protected def _addColumn(df: DataFrame, colName: String): DataFrame = {
      df.withColumn(colName, lit(colName))
    }
  }
  </code></pre>
  
  <p>And <em>it works</em>, but I was not entirely happy with this approach, because of the function signatures duplication. So I thought of another approach, using the (deprecated?) <code>implicit def</code> strategy:</p>
  
  <pre class="lang-scala prettyprint-override"><code>trait ColumnAdder {
    protected implicit def columnAdderImplicits(df: DataFrame): ColumnAdderDataFrame
  
    abstract class ColumnAdderDataFrame(df: DataFrame) {
      def addColumn(colName: String): DataFrame
    }
  }
  
  trait StringColumnAdder extends ColumnAdder {
    protected implicit def columnAdderImplicits(df: DataFrame): ColumnAdderDataFrame = new StringColumnAdderDataFrame(df)
  
    class StringColumnAdderDataFrame(df: DataFrame) extends ColumnAdderDataFrame(df) {
      def addColumn(colName: String): DataFrame = {
        df.withColumn(colName, lit(colName))
      }
    }
  }
  </code></pre>
  
  <p>(The full reproducible code, including an extra trait-module can be found <a href="https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/479856682517642/458157887798984/1554640918355970/latest.html">here</a>)</p>
  
  <p>So, I wanted to ask which approach is the best and if there may be another better way to achieve what I want.</p>