Immutable binary search tree using Scala
I think it would be an improvement to define an empty element. Currently you have no way to represent an empty collection. But that is required if you would want to integrate your data structure with scala collections.

(In scala collections, you usually build up an immutable data structure like a Set or Map by starting with the empty element and adding elements. The apply methods defined in the companion objects are just convenience methods)

Defining an empty element will also simplify your code a lot. For example: you won't have to use Option for left and right, but can just use the empty value if e.g. left does not contain elements. For iteration for example you don't have to check whether left or right is empty by checking for None, but just call the method on the child.

In the simplest case this will look something like this:

object BST {
  def empty[T](implicit c:(T,T) =&gt; Int) : BST[T] = new EmptyBST(c)
}

sealed abstract class BST[T] {
  // abstract: whatever methods you want to support
}

case class EmptyBST[T](c:(T,T) =&gt; Int) extends BST[T] {
  // trivial implementation of all methods for an empty BST
}

case class NonEmptyBST[T](left:BST[T], right:BST[T], value:T, c:(T,T) =&gt; Int) extends BST {
  // non-trivial implementation of all methods for the non-empty case
}


Another thing: using (T,T) => Int is perfectly fine for educational purposes. But if you want this to match the style of other scala collections, you should use scala.math.Ordering. There are already predefined orderings and some utility methods to create orderings for composite objects like tuples.

For the traversal, I would not return a List[T] of all elements but instead just implement the Traversable[T] trait by defining a foreach method for each traversal order. That is much more efficient in case the user is not interested in everything but just the first few elements. And if the user wants a List[T] he can always make one by calling .toList. Traversal using foreach uses side effects internally, but for the end user these are not observable, so it's OK.