1

Given this spinet of code in Scala:

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

That can be shortened to:

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

What actually the code does is renaming the operator ++ of Map[VertexId, Factor] and therefore: Is there a way to assign that operator to the variable? Like in this imaginary example:

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

And probably with type inference it would enough to write

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

Thanks

1
  • What is your question? Commented Oct 1, 2014 at 14:48

1 Answer 1

6

Unfortunately, no, because the "operators" in Scala are instance methods — not functions from a typeclass, like in Haskell.
Whey you write _ ++ _, you are creating a new 2-argument function(lambda) with unnamed parameters. This is equivalent to (a, b) => a ++ b, which is in turn equivalent to (a, b) => a.++(b), but not to (a, b) => SomeClass.++(a, b).

You can emulate typeclasses by using implicit arguments (see "typeclasses in scala" presentation)

You can pass "operators" like functions — which are not really operators. And you can have operators which look the same. See 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)

}

Here we define Concat typeclass and create an implementation for Int and we use operator-like name for the method in typeclass.

Because you can implement a typeclass for any type, you can use such trick with any type — but that would require writing quite some supporting code, and sometimes it is not worth the result.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.