Home > Software engineering >  Left handed equivalent of apply in Scala
Left handed equivalent of apply in Scala

Time:12-03

It's very easy to define something like a 2 dimensional Matrix class in Scala with an apply method that would let me elegantly access the values inside my Matrix. Quite simply one would do this :

class Matrix(val n: Int, val m: Int, val default: Double = 0) {
  val data: Array[Array[Double]] = Array.fill(n, m)(default)
  def apply(x: Int, y: Int): Double = data(x)(y)
}

This allows me to access elements in my matrix like so :

val matrix = new Matrix(3, 3)
println(matrix(2, 2))

What I'm after, however, is the ability to do the opposite, and actually assign values to a matrix using similar notation. Essentially I want the ability to write something like this :

matrix(2, 2) = 5

Is there any way to do this in Scala ? In C this is doable by overloading the parenthesis operator to return a reference rather than a copy (the former defines the setter and the latter the getter), and similarly in Python this is the distinction between the __getitem__ and __setitem__ magic methods (with the slight difference of applying to square brackets instead of parenthesis). Does Scala support such behavior or am I stuck having to either directly access the data member and/or just writing a setter function ?

CodePudding user response:

Take Array#update as example:

  /** Update the element at given index.
   *
   *  Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`.
   *
   *  @param    i   the index
   *  @param    x   the value to be written at index `i`
   */
  def update(i: Int, x: T): Unit

Try implementing an update:


class Matrix(val n: Int, val m: Int, val default: Double = 0) {
  ...
  def update(x:Int, y: Int, value: Double): Unit =
   ???
}


matrix(2,2) = 5d

EDIT:
You can actually use:

  • def update(x:Int, y: Int, value: Double): Unit

instead of:

  • def update(coord: (Int,Int), value: Double): Unit.

and get exactly the syntax you desired.

  • Related