Search code examples
scalatype-deduction

Scala `+` functor defined on Int maps from Short to Int?


I'm writing a custom tree/graph container for smaller serialisation, and i'm getting a compiler error, apparently adding something to a short produces an Int.

def traverse(tree : Tree, level : Short = 0, pos : Short = 0) {
  buf(level) += tree
  var pos : Short = -1
  tree.getChildrenAsList.iterator().foreach { z=>
    pos += 1
    traverse(z, level + 1 ,pos)
  }
}

[error] /Users/hassan/code/scala/avro/src/main/scala/edu/hsyed/nlp/MyTree.scala:33: type mismatch;
[error]  found   : Int
[error]  required: Short
[error]         traverse(z, level + 1 ,pos)

I'm having to do this, which seems a bit unusual because of scala's impressive type deduction :

def traverse(tree : Tree, level : Short = 0, pos : Short = 0) {
      buf(level) += tree
      var pos : Short = -1
      tree.getChildrenAsList.iterator().foreach { z=>
        pos = (pos + 1).toShort
        traverse(z, (level + 1).toShort ,pos)
      }
    }

edit

Aah the question is, how do I get around this ?


Solution

  • You could create additional method for sum of Short.

    There is already such methods in scala in Numeric type class:

    import scala.math.Numeric
    
    val ns = implicitly[Numeric[Short]]
    val s = 1: Short
    
    ns.plus(s, s)
    // Short = 2
    
    ns.times(3, 2)
    // Short = 6
    

    In case you can abstract over Short type you could use + method from Numeric.Implicits like this:

    import Numeric.Implicits._
    def traverse[T: Numeric](tree: Tree[T], level: T, pos: T) {
      val one = implicitly[Numeric[T]].one
    
      buf(level) += tree
      var pos: T = -one
      tree.getChildrenAsList.iterator().foreach { z =>
        pos += one
        traverse(z, level + one, pos)
      }
    }
    

    You could also use |+| from scalaz as replacement for +:

    import scalaz._, Scalaz._
    
    s |+| s
    // Short = 2