Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating `**` power operator for Scala?

I quite like the ** syntax for pow, available in many languages (such as Python).

Is it possible to introduce this into Scala, without modifying the Scala 'base' code?

My attempt at an Int only one:

import scala.math.pow
implicit class PowerInt(i: Int) {
    def `**`(n: Int, b: Int): Int = pow(n, b).intValue
}

(see it failing on IDEone)

like image 732
A T Avatar asked Nov 03 '13 01:11

A T


People also ask

Does Java have power operator?

pow() is used to calculate a number raise to the power of some other number. This function accepts two parameters and returns the value of first parameter raised to the second parameter.


2 Answers

this works for me: (problem#1 pow is defined on doubles, problem#2 extending anyval) (also there is no point in having those backticks in the methodname?)

import scala.math.pow

object RichIntt {

  implicit class PowerInt(val i:Double) extends AnyVal {
    def ** (exp:Double):Double = pow(i,exp)
  }

  def main(args:Array[String])
  {
    println(5**6)
  }

}
like image 94
Stefan Kunze Avatar answered Oct 11 '22 15:10

Stefan Kunze


This answer is 2 years late, still for the benefit of others I'd like to point out that the accepted answer unnecessarily extends from AnyVal.

There is just a minor bug that needs to be fixed in the original answer. The def ** method needs only one parameter, i.e. the exponent as the base is already passed in the constructor and not two as in the original code. Fixing that and removing the backticks results in:

import scala.math.pow
implicit class PowerInt(i: Int) {
    def ** (b: Int): Int = pow(i, b).intValue
}

Which works as expected as seen here.

Scala compiler will cast an Int to a PowerInt only if the method that is called on it is undefined. That's why you don't need to extend from AnyVal.

Behind the scenes, Scala looks for an implicit class whose constructor argument type is the same as the type of the object that is cast. Since the object can have only one type, implicit classes cannot have more than one argument in their constructor. Moreover, if you define two implicit classes with the same constructor type, make sure their functions have unique signatures otherwise Scala wouldn't know which class to cast to and will complain about the ambiguity.

like image 18
Swayam Avatar answered Oct 11 '22 16:10

Swayam