scalatraits

How to declare a one-method trait


In scala, there are multiple ways to declare a trait with only one method

trait OneMethod extends (A => B)

trait OneMethod {
  def myMethod(a: A) : B
}

What are the pro and con of each solution ?


Solution

  • By extending (A => B), you are saying that OneMethod is a function, and can be used directly as such:

    trait TraitA extends (Int => String)
    class ClassA extends TraitA { def apply(i: Int) = i.toString }
    
    val a = new ClassA
    (1 to 5).map(a)      // IndexedSeq[String] = Vector(1, 2, 3, 4, 5)
    

    If you don't extend (A => B), you can't do that; instead, you'd have to tell it explicitly what the method name is:

    trait TraitB { def myMethod(i: Int): String }
    class ClassB extends TraitB { def myMethod(i: Int) = i.toString }
    
    val b = new ClassB
    (1 to 5).map(b)              // error, required: Int => ?
    (1 to 5).map(b.myMethod)     // IndexedSeq[String] = Vector(1, 2, 3, 4, 5)
    

    So: extending (A => B) makes your class a bit more flexible in its use, with less verbosity. On the other hand, if you want a more descriptive name than apply, you can do version B.

    Also worth noting: neither version restricts the trait to having only one method; you can add extra methods to either.