I have a ADT as follows:
sealed trait Tree[A]
case object EmptyTree extends Tree[Nothing]
case class Leaf[A](value: A) extends Tree[A]
case class Node[A](op: Seq[A] => A, branches: Tree[A]*) extends Tree[A]
When i try to build a function to randomly create Trees i get a problem with the EmptyTree, the type system does not let go through
  def create(acc: Tree[A], currentDepth: Int): Tree[A] = currentDepth match {
    case maxDepth => Leaf(terminalSet(r.nextInt(terminalSet.length)))
    case 0 => {
      val op_pos = r.nextInt(fSetLength)
      val branches: Seq[Tree[A]] = for (i <- 0 to r.nextInt(fSetLength)) yield create(EmptyTree, currentDepth+1)
      Node(functionSet(op_pos)._1, branches:_*)
    }
    case _ => {
      if (r.nextFloat() <= probF) {
        val op_pos = r.nextInt(fSetLength)
        val branches = for (i <- 0 to r.nextInt(fSetLength)) yield create(EmptyTree, currentDepth + 1)
        Node(functionSet(op_pos)._1, branches:_*)
      }
      else
        Leaf(terminalSet(r.nextInt(terminalSet.length)))
    }
  }
  create(EmptyTree, 0) 
basically in create(EmptyTree, currentDepth + 1) it complains that it is expecting a Tree[A] and is receiving a EmptyTree.type 
                        
The compiler objections are justified. The compiler expects
Tree[A]and you are passingEmptyTree, whose super type isTree[Nothing]. A priori, there's no subtyping relationship between these two types.What you want is
Treeto be covariant: ifX <: YthenTree[X] <: Tree[Y]. Then, asNothing <: Afor anyAyou getEmptyTree.type <: Tree[A]and you can always passEmptyTreewhenever you need aTree[A].The syntax for declaring the
Aparameter inTreecovariant isTree[+A]; change that and your code should compile.This is a good post on covariance and contravariance in Scala: Be friend with covariance and contravariance
UPDATE After your questioning answer I have actually looked at your constructors for
Treeand, as defined, you cannot makeTreecovariant. Sadly, the compiler won't complain (you see, it should actually complain more). YouropinNodeis contravariant onSeq[A], and thus you cannot makeNodecovariant. At this point you might be thinking:Well, through making its supertype
Treecovariant Node becomes so in practice.scalacshould actually check that all sub type constructors of a covariant one are (or could be made) covariant. Anyway, code showing this follows:UPDATE 2 Back to your original question :) I'd leave your
Treetype invariant, and have anEmptyTree[A]()case class; it is a pity that there are no parameterless value classes.