2014-10-01 135 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) 

} 

在这里我们定义的毗连类型类,并为诠释的实施和我们使用的运营商,如姓名为类型类的方法。

因为你可以实现任何类型的一个类型类,你可以使用这种伎俩与任何类型的 - 但这需要编写一段代码支持,有时它是不值得的结果。