2014-02-18 85 views
1

我正在爲較小的序列化寫一個自定義的樹/圖容器,並且我得到一個編譯器錯誤,顯然增加了一些內容以產生一個Int。從Int到Int映射從Short到Int定義的Scala`+`functor?

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) 

我不得不這樣做,這似乎是因爲Scala的令人印象深刻的類型推演的有點不尋常:

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) 
     } 
    } 

編輯

啊哈,問題是,我怎麼弄在這附近?

+0

這看起來像[Java的原始數值shenanigans](http://stackoverflow.com/questions/2720738/java-short-and-casting)的後果。 –

回答

2

您可以爲Short創建額外的方法。

已經有這樣的方法在scalaNumeric型類:

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 

在情況下,你可以抽象在Short類型,你可以使用+方法從Numeric.Implicits這樣的:

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) 
    } 
} 

你可以也可使用scalaz|+|代替+

import scalaz._, Scalaz._ 

s |+| s 
// Short = 2 
+0

非常高質量的答案,尤其是代碼的第二部分。第一部分本身不足以獲得Numeric類的意圖/用例。這也是爲什麼scalaz,以及爲什麼monoids自從你展示'.one'方法的良好橋樑。在某些時候,我需要明白'暗含'的含義:D –