Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Currying Math Operators in Scala

Tags:

scala

I want to create a simple Map from math operators to the relevant functions:

var ops = Map("+" -> +, "-" -> -)

How would I do this in Scala?

like image 248
Vlad the Impala Avatar asked Feb 20 '12 04:02

Vlad the Impala


2 Answers

If you want the functions to be curried, the following is probably the most concise way to do it.

scala> val ops: Map[String, Int => Int => Int] = Map(
     |   "+" -> (x => y => x + y),
     |   "-" -> (x => y => x - y)
     | )
ops: Map[String,Int => Int => Int] = Map(+ -> <function1>, - -> <function1>)

This map however is only limited to Ints. If you want generic operations, you will have to use Numeric context bound.

scala> def ops[N : Numeric]: Map[String, N => N => N] = {
     |   import Numeric.Implicits._
     |   Map(
     |     "+" -> (x => y => x + y),
     |     "-" -> (x => y => x - y)
     |   )
     | }
ops: [N](implicit evidence$1: Numeric[N])Map[String,N => N => N]

A major caveat with this approach is that a map gets created every time you call ops.

like image 51
missingfaktor Avatar answered Oct 19 '22 05:10

missingfaktor


val ops = Map("+" -> ((_: Int) + (_: Int)), "-" -> ((_: Int) - (_:Int)))

or

val ops = Map[String, (Int, Int) => Int]("+" -> (_+_), "-" -> (_-_))

or even, for actual currying,

val ops = Map("+" -> ((_: Int) + (_: Int)).curried, "-" -> ((_: Int) - (_:Int)).curried)

These functions are all bind to Int. Well, Scala is not a point-free programming language, it's an object oriented one, and one in which there's no superclass common to all numeric types. Anyway, if you object to that, then you have an entirely different problem, which was asked and answered many times here on Stack Overflow (in fact, it was my first Scala question, iirc).

like image 32
Daniel C. Sobral Avatar answered Oct 19 '22 05:10

Daniel C. Sobral