How to define a list of functions of the same arity in Scala?

In different Lisp it is possible to create a sequence of functions as if they were only normal values:

(def ops [+ - * /]) 

What can I repeat, again, as if they were just normal values:

 (doseq [op ops] // (doseq (op ops) is like for (op <- ops) in scala (println (op 1 2 3 4))) 

Now I tried several things in Scala, and all of them failed:

 scala> List(+, -, *, /) <console>:1: error: illegal start of simple expression List(+, -, *, /) ^ scala> List[Double => Double](+, -, *, /) <console>:1: error: illegal start of simple expression List[Double => Double](+, -, *, /) ^ scala> List[Double => Double](+_, -_, *_, /_) <console>:8: error: not found: value * List[Double => Double](+_, -_, *_, /_) ^ <console>:8: error: not found: value / List[Double => Double](+_, -_, *_, /_) ^ 

So, what is the correct procedure for defining a list of functions / operators in Scala?

+6
source share
2 answers

The problem is that these functions are binary operators, i.e. take two operands and return one. Therefore you should use:

 List[(Double, Double) => Double](_ + _, _ - _, _ * _, _ / _) 
+11
source

In Scala, most value-level operators are actually inherited instance methods (perhaps all of them are not sure if counter macros exist). Therefore, when you say, say, by adding two values โ€‹โ€‹of type Double , you really mean the method of the first value that takes the second value as a parameter. The syntax for the familiar infix operator is just sugar . In other words,

 scala> 5.7 + 6.3 res0: Double = 12.0 

really just a beautiful shorthand for:

 scala> 5.7.+(6.3) res1: Double = 12.0 

As @ bluenote10 already mentioned , you can capture these operators by creating an anonymous function that takes both the first instance and its operand as parameters and returns the result + :

 scala> (lhs: Double, rhs: Double) => lhs + rhs res2: (Double, Double) => Double = <function2> 

Or, as in the @ bluenote10 example, if the type can be inferred (for example, in a list with the type provided), you can use the syntax of a pretty underscore:

 scala> val doublePlus: (Double, Double) => Double = _ + _ doublePlus: (Double, Double) => Double = <function2> 
+1
source

Source: https://habr.com/ru/post/976243/


All Articles