title: How to work with abstract type members in Scala
body: <p>I'm running into issues with the following code (heavily simplified). Looks like the problem may be with the way I use abstract type members. I would appreciate someone pointing out and explaining what I'm doing wrong here. Compiler error at the bottom.
  I'm using Scala version 2.12.</p>
  
  <pre><code>trait DataType {
      type A
  
      def convert(value: String): A
      def convertToString(value: A): String
  }
  
  case object IntType extends DataType {
      type A = Int
  
      def convert(value: String): A = value.toInt
      def convertToString(value: A): String = value.toString
  }
  
  trait Codec[T &lt;: DataType] {
      val dtype: T
  
      def encode(data: Array[String]): Array[T#A]
      def decode(data: Array[T#A]): Array[String]
  }
  
  class CodecImp[T &lt;: DataType](val dtype: T)(implicit tag: ClassTag[T#A]) extends Codec[T] {
      def encode(data: Array[String]): Array[T#A] = {
          Array[T#A](dtype.convert(data(0)))
      }
  
      def decode(data: Array[T#A]): Array[String] = {
          Array[String](dtype.convertToString(data(0)))
      }
  }
  
  val cod = new CodecImp(IntType)
  val encoded = cod.encode(Array("1", "2", "3")) // expecting: Array[IntType.A]
  val decoded = cod.decode(encoded) // expecting: Array[String]
  </code></pre>
  
  <p>Compiler error.</p>
  
  <pre><code>Error:(30, 50) type mismatch;
   found   : T#A
   required: CodecImp.this.dtype.A
          Array[String](dtype.convertToString(data(0)))                
                   ^
  </code></pre>