title: How to dynamically create an Enum type in Scala?
body: <p>I have a basic enum type Currency that will include all major currencies traded e.g. <code>EUR</code>, <code>USD</code>, <code>JPY</code>, etc. This code I can write or generate one time. However, I'd also like to have strong enum type for all currency pair combinations e.g. <code>EURCHF</code>, <code>USDCHF</code>, etc. Is there any provision in Scala that would allow me to build such a derived enum type dynamically? I could also do it with some script generator from outside ... but I wonder whether it would be possible.</p>
  
  <pre><code>object Ccy extends Enumeration {
     type Type = Value
     val USD = Value("USD")
     val CHF = Value("CHF")
     val EUR = Value("EUR")
     val GBP = Value("GBP")
     val JPY = Value("JPY")
  }
  
  object CcyPair extends Enumeration {
     type Type = Value
     // ??? Ccy.values.toSeq.combinations(2) ...   
  }
  </code></pre>
  
  <p><strong>UPDATE</strong> using the accepted answer as reference this was my solution implementation:</p>
  
  <pre><code>import scala.language.dynamics
  
  object CcyPair extends Enumeration with Dynamic {
    type Type = Value
    /* 
     * contains all currency combinations including the symmetric AB and BA
     */
    private val byCcy: Map[(Ccy.Value, Ccy.Value), Value] =
      Ccy.values.toSeq.combinations(2).map { case Seq(c1, c2) =&gt;
        Seq(
          (c1, c2) -&gt; Value(c1.toString + c2.toString),
          (c2, c1) -&gt; Value(c2.toString + c1.toString)
        )
      }.flatten.toMap
    /** 
     * reverse lookup to find currencies by currency pair, needed to find
     * the base and risk components.
     */ 
    private val revByCcy = byCcy.toSeq.map { case (((ccyRisk, ccyBase), ccyPair)) =&gt;
      ccyPair -&gt; (ccyRisk, ccyBase)
    }.toMap
  
    def apply(ccy1: Ccy.Value, ccy2: Ccy.Value): Value = {
      assert(ccy1 != ccy2, "currencies should be different")
      byCcy((ccy1, ccy2))
    }
  
    implicit class DecoratedCcyPair(ccyPair: CcyPair.Type) {
      def base: Ccy.Type = {
        revByCcy(ccyPair)._1
      }
  
      def risk: Ccy.Type = {
        revByCcy(ccyPair)._2
      }
  
      def name: String = ccyPair.toString()
    }
  
    def selectDynamic(ccyPair: String): Value = withName(ccyPair)
  }
  </code></pre>
  
  <p>and then I can do things like:</p>
  
  <pre><code>val ccyPair = CcyPair.EURUSD
  // or
  val ccyPair = CcyPair(Ccy.EUR, Ccy.USD) 
  
  // and then do
  println(ccyPair.name)
  // and extract their parts like:
  // print the base currency of the pair i.e. EUR
  println(CcyPair.EURUSD.base) 
  // print the risk currency of the pair i.e. USD
  println(CcyPair.EURUSD.risk)
  </code></pre>