2014-10-01 64 views
1

指定的運營商到可變鑑於這種尖晶石的代碼在斯卡拉:在斯卡拉

val mapMerge : (Map[VertexId, Factor], Map[VertexId, Factor]) => Map[VertexId, Factor] = (d1, d2) => d1 ++ d2 

,可以縮短爲:

val mapMerge : (Map[VertexId, Factor], Map[VertexId, Factor]) => Map[VertexId, Factor] = _ ++ _ 

什麼實際的代碼不會被重命名操作++ Map [VertexId,Factor],因此:有沒有辦法將該運算符分配給該變量?就像在這個虛構的例子:

val mapMerge : (Map[VertexId, Factor], Map[VertexId, Factor]) => Map[VertexId, Factor] = Map.++ 

,可能與類型推斷這將足夠寫

val mapMerge = Map[VertexId,Factor].++ 

感謝

+0

什麼是你的問題? – rightfold 2014-10-01 14:48:33

回答

6

不幸的是,沒有,因爲「運營商」,在斯卡拉是例如方法 - 不是來自類型類的函數,就像在Haskell中一樣。
乳清你寫_ ++ _,你正在創建一個未命名的參數的新2參數的函數(拉姆達)。這相當於(a, b) => a ++ b,這又相當於(a, b) => a.++(b),而不是(a, b) => SomeClass.++(a, b)

您可以通過使用隱式參數,模擬類型類(見"typeclasses in scala" presentation

您可以通過「運營商」之類的功能 - 這是不是真正的運營商。你可以讓運營商看起來一樣。見this example

object Main { 

    trait Concat[A] { def ++ (x: A, y: A): A } 
    implicit object IntConcat extends Concat[Int] { 
     override def ++ (x: Int, y: Int): Int = (x.toString + y.toString).toInt 
    } 

    implicit class ConcatOperators[A: Concat](x: A) { 
     def ++ (y: A) = implicitly[Concat[A]].++(x, y) 
    } 

    def main(args: Array[String]): Unit = { 
     val a = 1234 
     val b = 765 

     val c = a ++ b // Instance method from ConcatOperators — can be used with infix notation like other built-in "operators" 

     println(c) 

     val d = highOrderTest(a, b)(IntConcat.++) // 2-argument method from the typeclass instance 

     println(d) 
     // both calls to println print "1234765" 
    } 

    def highOrderTest[A](x: A, y: A)(fun: (A, A) => A) = fun(x, y) 

} 

在這裏我們定義的毗連類型類,併爲詮釋的實施和我們使用的運營商,如姓名爲類型類的方法。

因爲你可以實現任何類型的一個類型類,你可以使用這種伎倆與任何類型的 - 但這需要編寫一段代碼支持,有時它是不值得的結果。