title: scala cake pattern - can I have multiple layers of cake?
body: <p>so say I have two dependencies in my app, a connection to some pub sub system, and a connection to a database. I can do something like</p>
  
  <pre><code>trait DB {
      def lookup(query:String):String
  }
  
  trait PubSub {
      def subscribe(key:String, callback:String =&gt; Any)
  }
  </code></pre>
  
  <p>then I can write my logic like</p>
  
  <pre><code>trait Functionality { this:DB with PubSub =&gt; 
      def doSomething() {
          val key = lookup("get key")
          subscribe(key, data =&gt; println(data))
      }
  }
  </code></pre>
  
  <p>and then my app can be like</p>
  
  <pre><code>object Awesome extends App {
  
      object repository extends Functionality with DB with PubSub {
          def lookup(query:String) = "some key"
          def subscribe(key:String, callback:String =&gt; Any) {
              scala.concurrent.ops.spawn { while(true) { callback(key) ; Thread.Sleep(1000) } } 
          }
      }
      repository.doSomething()
  }
  </code></pre>
  
  <p>and all is well and good in the world. </p>
  
  <p>But what if I want connections to two pub sub systems that share the same database implementation in the same app?</p>
  
  <p>I want to do something like</p>
  
  <pre><code>object Awesome2 extends App {
      object repository extends DB {
          def lookup(query: String): String = "some other key"
  
          object connection1 extends Functionality with PubSub with DB {
              def subscribe(key: String, callback: (String) =&gt; Any) {
                  scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
              }
          }
  
          object connection2 extends Functionality with PubSub with DB {
              def subscribe(key: String, callback: (String) =&gt; Any) {
                  scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
              }
          }
      }
  }
  </code></pre>
  
  <p>where the objects in the second layer of cake (implicitly?) slurp in the DB implementation from the parent level.</p>
  
  <p>But the scala compiler tells me</p>
  
  <pre><code>error: object creation impossible, since method lookup in trait DB of type (query:String) String is not defined
  object connection2 extends Functionality with PubSub with DB {
  </code></pre>
  
  <p>if I do the following then it does what I want</p>
  
  <pre><code>object Awesome3 extends App {
      object repository extends DB {
          override def lookup(query: String): String = "some other key"
  
          object connection1 extends Functionality with PubSub with DB {
              def subscribe(key: String, callback: (String) =&gt; Any) {
                  scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
              }
  
              def lookup(query: String): String = repository.lookup(query)
          }
  
          object connection2 extends Functionality with PubSub with DB {
              def subscribe(key: String, callback: (String) =&gt; Any) {
                  scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
              }
  
              def lookup(query: String): String = repository.lookup(query)
          }
      }
      repository.connection1.doSomething()
      repository.connection2.doSomething()
  }
  </code></pre>
  
  <p>but this is kind of messy </p>
  
  <p>I can add this trait</p>
  
  <pre><code>trait DB_Base extends DB {
  
      private val db:DB = this
  
      trait DB_Layer extends DB {
          def lookup(query:String):String = db.lookup(query)
      }
  }
  </code></pre>
  
  <p>and then the following works </p>
  
  <pre><code>object Awesome4 extends App {
      object repository extends DB_Base {
          override def lookup(query: String): String = "some other key"
  
          object connection1 extends Functionality with PubSub with DB_Layer {
              def subscribe(key: String, callback: (String) =&gt; Any) {
                  scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
              }
          }
  
          object connection2 extends Functionality with PubSub with DB_Layer {
              def subscribe(key: String, callback: (String) =&gt; Any) {
                  scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
              }
          }
      }    
      repository.connection1.doSomething()
      repository.connection2.doSomething()
  }
  </code></pre>
  
  <p>so now I have two layers. How do I get three? I feel like I'm losing the plot. </p>