In Scala, if I have a class called Vector2D and I want to make some implicit conversions for it. Currently, I have this function placed in the Vector2D: implicit def fromFloatTuple(tuple: (Float, Float)): Vector2D = new Vector2D(tuple._1, tuple._2)
I can do the following successfully val x: Vector2D = (1f, 1f). However, I cannot do something like: val x: Float = (1f, 1f).length() (obviously length is defined for Vector2D). Why does this not work, I would expect it to be converted to something like val x: Float = fromFloatTuple((1f, 1f)).length() but it is not. How do I get this effect in Scala?
Also now that I think of it, how could I make this function accept other numerical types as well without making a function for each combination of all numerical types (not a problem with a 2D vector but quite unclean for a 4D vector).
When you have target or source type Vector2D, the compiler looks in the companion object of Vector2D; in val x: Float = (1f, 1f).length() it doesn't. Looking for all possible types for implicit conversion would slow compilation very much, and Scala compiler is already slow (though improving).
You need to bring fromFloatTuple into scope by importing it:
import your.package.Vector2D._ // or just fromFloatTuple instead of _
This is exactly how it is supposed to work:
import scala.language.implicitConversions
object Test {
class Vector2D(x: Float, y: Float) { def length(): Float = x + y }
implicit def fromFloatTuple(tuple: (Float, Float)): Vector2D = Vector2D(tuple._1, tuple._2)
val x: Float = (1f, 1f).length()
For the more generic case you might want to look at scala.math.Numeric.
case class Vector4D[N](a: N, b: N, c: N, d: N)(implicit n: Numeric[N]) {
import n._
def length(): N = a + b + c + d
}
implicit def c2V4D[N: Numeric](tup: (N, N, N, N)): Vector4D[N] = new Vector4D(tup._1, tup._2, tup._3, tup._4)
println(Vector4D(1,2,3,4).length())
println(Vector4D(1,2,3,4.5).length())
println((1,2,3,4).length())
}
Related
Multiplying x and 2 doesn't work. Scala version is 2.13.8.
import Integral.Implicits._
object hello {
def f[T:Integral](x: T): T = x * 2
val x: Int = 1
f(x)
}
type mismatch;
found : Int(2)
required: T
def f[T:Integral](x: T): T = x * 2
You need to convert 2 into a T.
Thankfully, the instance of the Integral typeclass for T (which is passed implicitly thanks to [T: Integral] has a fromInt method which can convert an Int like 2 into a T:
def f[T: Integral](x: T): T = {
val two = implicitly[Integral[T]].fromInt(2) // summons the typeclass instance
x * two
}
Adding to what Levi mentioned, you'll need to import:
import scala.math.Integral.Implicits.infixIntegralOps
Still, you can simplify it to just:
def f[T: Integral](x: T): T = x * Integral[T].fromInt(2)
Taking advantage of the Integral companion object's apply method which takes an implicit of Integral[T] and returns it. It's exactly what implicitly does, only implicitly is more generic.
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 ?
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.
I was wondering how one would implement an infinite curried add function, for the case of explanation i would stick to scala.
I know how to prepare a simple curry like
def add(a: Int): Int => Int = {
def iadd(b: Int): Int = {
a + b
}
iadd
}
add(4)(5) // 9
How would i got about implementing add(5)(4)(x1)(x2)..(xn)
The Smart Way
The question is the comments is well-posed: when do you stop the currying and produce a result?
One solution is to stop the recursion by calling the function with zero arguments. Scala's overloading with let us do this.
add(1)(2)(3)(4)() // The () indicates that we're done currying
This is relatively straightforward. We just need a class with an apply that returns a new instance of itself
// A class with an apply method is callable like a function
class Adder(val acc: Int) {
def apply(a: Int): Adder =
new Adder(acc + a)
def apply(): Int =
acc
}
def add: Adder = new Adder(0)
println(add(1)(2)(3)(4)()) // 10
If you ever had a real reason to do this, this would be the way I would recommend. It's simple, easy to read, and adds very little boilerplate on top of the currying.
The Slightly Unhinged Way
But what fun is simple and logical? Let's get rid of those silly parentheses at the end, eh? We can do it with Scala's implicit conversions. First, we'll need to import the feature, so that Scala will stop warning us that what we're doing is silly and not a good idea.
import scala.language.implicitConversions
Then we make it so that Adder can be converted to Int
// Don't do this in real code
implicit def adderToInt(adder: Adder): Int =
adder()
Now, we don't need those parentheses at the end. We do, however, need to indicate to the type system that we want an Int.
val result: Int = add(1)(2)(3)(4)
println(result) // 10
Passing the result to a function which takes an Int, for instance, would also suffice.
Comments
Since you mentioned functional programming in general, I will note that you can do similar tricks in Haskell, using typeclasses. You can see this in action in the standard library with Text.PrintF. Note that since Haskell functions always take one argument, you'll need to have a sentinel value to indicate the "end" of the arguments (() may suffice, depending on how generic your argument types are).
If you want to reinterpret every integer n as function n.+, then just do it:
implicit class Add(val x: Int) extends AnyVal { def apply(i: Int) = x + i }
val add = 0
or even shorter (with implicit conversions):
implicit def asAdd(n: Int): Int => Int = n.+
val add = 0
Example:
add(1)(2)(3)(4) // res1: Int = 10
There is no such thing as "infinitely curryable", it's not a meaningful notion.
Well, this is not exactly infinite currying, but it gives you the something similar.
final class InfiniteCurrying[A, B] private (acc: A, op: (A, B) => A) {
final val run: A = acc
final def apply(b: B): InfiniteCurrying[A, B] =
new InfiniteCurrying(
acc = op(acc, b),
op,
)
}
object InfiniteCurrying {
def add(initial: Int): InfiniteCurrying[Int, Int] =
new InfiniteCurrying(
acc = initial,
op = (acc, b) => acc + b
)
}
import InfiniteCurrying._
val r = add(10)(20)(30)
r.run // res: Int = 60
The title describes a specific problem I encountered when trying to solve a more general problem: how to separate a type conversion concern from a calculation concern. If I can solve that larger problem by another means than partially applied functions, great!
I'm using a type class, NumberOps, to represent operations on numbers. This code is paired down, but still exhibits the problem and expresses my intent. The first part simply defines the type class and a couple of implementations.
trait NumberOps[T] { // the type class (simplified for debugging)
def neg(x: T): T // negate x
def abs(x: T): T // absolute value of x
// ... over 50 more operations
def toFloating(x:T):AnyVal // convert from native to Float or Double, preserving precision
def fromFloating(f:AnyVal):T // convert from Float or Double to native
// ... also to/from Integral and to/from Big
}
object NumberOps { // Implements NumberOps for each type
import language.implicitConversions
implicit object FloatOps extends NumberOps[Float] {
def neg(x: Float): Float = -x
def abs(x: Float): Float = x.abs
def toFloating(f:Float):Float = f
def fromFloating(x:AnyVal):Float = {
x match {
case f:Float => f
case d:Double => d.toFloat
}
}
}
implicit object DoubleOps extends NumberOps[Double] {
def neg(x: Double): Double = -x
def abs(x: Double): Double = x.abs
def toFloating(d:Double):Double = d
def fromFloating(x:AnyVal):Double = {
x match {
case f:Float => f.toDouble
case d:Double => d
}
}
}
// ... other implicits defined for all primitive types, plus BigInt, BigDec
} // NumberOps object
All well and good. But now I want to implement NumberOps for complex numbers. A complex number will be represented as a 2-element array of any numeric type already defined (i.e. all primitive types plus BigInt and BigDecimal).
The intent with this code is to avoid combinatorial explosion of number types with numeric operations. I had hoped to achieve this by separating Concern A (type conversion) from Concern B (generic calculation).
You'll notice that "Concern A" is embodied in def eval, while "Concern B" is defined as a generic method, f, and then passed as a partially applied function (f _) to method eval. This code depends on the earlier code.
object ImaginaryOps { // Implements NumberOps for complex numbers, as 2-element arrays of any numeric type
import language.implicitConversions
import reflect.ClassTag
import NumberOps._
implicit def ComplexOps[U: NumberOps : ClassTag]: NumberOps[Array[U]] = { // NumberOps[T] :: NumberOps[Array[U]]
val numOps = implicitly[NumberOps[U]]
type OpF2[V] = (V,V) => NumberOps[V] => (V,V) // equivalent to curried function: f[V](V,V)(NumberOps[V]):(V,V)
// Concern A: widen x,y from native type U to type V, evaluate function f, then convert the result back to native type U
def eval[V](x:U, y:U)(f:OpF2[V]):(U,U) = {
(numOps.toFloating(x), numOps.toFloating(y), f) match {
case (xf:Float, yf:Float, _:OpF2[Float] #unchecked) => // _:opF #unchecked permits compiler type inference on f
val (xv,yv) = f(xf.asInstanceOf[V], yf.asInstanceOf[V])(FloatOps.asInstanceOf[NumberOps[V]])
(numOps.fromFloating(xv.asInstanceOf[Float]), numOps.fromFloating(yv.asInstanceOf[Float]))
case (xd:Double, yd:Double, _:OpF2[Double] #unchecked) => // _:opF #unchecked permits compiler type inference on f
val (xv,yv) = f(xd.asInstanceOf[V], yd.asInstanceOf[V])(DoubleOps.asInstanceOf[NumberOps[V]])
(numOps.fromFloating(xv.asInstanceOf[Double]), numOps.fromFloating(yv.asInstanceOf[Double]))
}
} // eval
new NumberOps[Array[U]]{ // implement NumberOps for complex numbers of any type U
def neg(a: Array[U]): Array[U] = a match { case (Array(ax, ay)) =>
def f[V](xv:V, yv:V)(no:NumberOps[V]):(V,V) = (no.neg(xv), no.neg(yv)) // Concern B: the complex calculation
val (xu,yu) = eval(a(0), a(1))(f _) // combine Concern A (widening conversion) with Concern B (calculation)
a(0) = xu; a(1) = yu; a
}
def abs(a: Array[U]): Array[U] = a match { case (Array(ax, ay)) =>
def f[V](xv:V, yv:V)(no:NumberOps[V]):(V,V) = (no.abs(xv), no.abs(yv)) // Concern B: the complex calculation
val (xu,yu) = eval(a(0), a(1))(f _) // combine Concern A (widening conversion) with Concern B (calculation)
a(0) = xu; a(1) = yu; a
}
def toFloating(a:Array[U]):AnyVal = numOps.toFloating( a(0) )
def fromFloating(x:AnyVal):Array[U] = Array(numOps.fromFloating(x), numOps.fromFloating(x))
}
} // implicit def ComplexOps
} // ImaginaryOps object
object TestNumberOps {
def cxStr(a:Any) = { a match { case ad: Array[Double] => s"${ad(0)} + ${ad(1)}i" } }
def cxUnary[T:NumberOps](v: T)(unaryOp:T => T): T = {
val ops = implicitly[NumberOps[T]]
unaryOp(v)
}
def main(args:Array[String]) {
println("TestNo4")
import ImaginaryOps._
val complexDoubleOps = implicitly[NumberOps[Array[Double]]]
val complex1 = Array(1.0,1.0)
val neg1 = cxUnary(complex1)(complexDoubleOps.neg _)
val abs1 = cxUnary(neg1)(complexDoubleOps.abs _)
println(s"adz1 = ${cxStr(complex1)}, neg1 = ${cxStr(neg1)}, abs1 = ${cxStr(abs1)}, ")
}
} // TestNumberOps
Now this code compiles, but at runtime I get a class cast exception:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to scala.runtime.Nothing$
at ImaginaryOps$$anon$1$$anonfun$1.apply(Experiment4.scala:68)
at ImaginaryOps$.ImaginaryOps$$eval$1(Experiment4.scala:60)
at ImaginaryOps$$anon$1.neg(Experiment4.scala:68)
at TestNumberOps$$anonfun$3.apply(Experiment4.scala:97)
at TestNumberOps$$anonfun$3.apply(Experiment4.scala:97)
at TestNumberOps$.cxUnary(Experiment4.scala:89)
at TestNumberOps$.main(Experiment4.scala:97)
at TestNumberOps.main(Experiment4.scala)
I understand why this exception occurs. It's because the compiler couldn't resolve the type V of def f[V], so when it gets passed to method eval as (f _), its generic type V has been changed to scala.runtime.Nothing.
Having struggled without success and after searching futilely online, I'm hoping to find a useful suggestion here. Probably I'm making this harder than it is, but with Scala's strong type system there ought to be a solution. The problem is how to tell the compiler to use this type in evaluating this function.
What you want to do is to use a derived type class for your complex number.
Consider the following simplified scenario,
trait Addable[A] {
def apply(a: A, b: A): A
}
implicit val intAddable: Addable[Int] = new Addable[Int] {
def apply(a: Int, b: Int): Float = a + b
}
implicit val floatAddable: Addable[Float] = new Addable[Float] {
def apply(a: Float, b: Float): Float = a + b
}
implicit final class AddOps[A](a: A) {
def add(b: A)(implicit addable: Addable[A]): A = addable(a, b)
}
which basically allows us to call, 1.add(2) allowing the scala compiler to infer that there is an addable for ints.
However what about for your complex type? Since we want to essentially say there exists an addable for any complex type which is composited of 2 types which follow the addable law we essentially define it like this,
implicit def complexAddable[A](implicit addable: Addable[A]): Addable[Array[A]] = {
new Addable[Array[A]] {
def apply(a: Array[A], b: Array[A]): Array[A] = {
Array(a(0).add(b(0)), a(1).add(b(1)))
}
}
}
which works because there is an Addable[A] in scope. Note that this of course the implicit cannot be created if an addable for A doesn't exist, and hence you have lovely compile time safety.
You can find usages of this pattern in the excellent functional libraries such as scalaz, cats, scodec et cetera, and is known from haskell as the type class pattern.
Is there a way to use shorter syntax when using context-bound type parameters? At the moment I have something like this
case class Vector2D[a : Numeric](x: a, y: a) {
val numA = implicitly[Numeric[a]]
def length2 = numA.plus(numA.times(x, x), numA.times(y, y))
}
and it makes more complex formulae unreadable.
Try this REPL session:
scala> case class Vector2D[T : Numeric](x: T, y: T) {
val numeric = implicitly[Numeric[T]]
import numeric._
def length2 = (x*x)+(y*y)
}
defined class Vector2D
scala> Vector2D(3,4).length2
res0: Int = 25
This is because Numeric contains an implicit conversion called mkNumericOps which you can import as shown above. If it didn't come out of the box, the way you could roll this yourself would be something like:
scala> implicit class NumericOps[T](val x: T) extends AnyVal { def +(y: T)(implicit n: Numeric[T]): T = n.plus(x, y)
| def *(y: T)(implicit n: Numeric[T]): T = n.times(x, y)
| }
defined class NumericOps
scala> case class Vector2D[a : Numeric](x: a, y: a) { def length2 = (x*x)+(y*y) }
defined class Vector2D
scala> Vector2D(3,4).length2
res0: Int = 25
If you make NumericOps not a value class (don't extend AnyVal) then the implicit Numeric can go on the constructor instead of each method, which might be better, or not really matter.
Anyway there's no need to write your own since Numeric already has mkNumericOps.
These "ops" classes are called the "enrich my library" pattern.
Numeric.Ops is here
and the implicit being imported to auto-create it is mkNumericOps on Numeric, here.
Just
import Numeric.Implicits._
then for every type that for which an implicit Numeric can be found
(importing just the NumericOps conversion of one Numeric instance as suggested by #Havoc P gives you finer control as to for which types operations are available, but most of the time, Numeric.Implicits should be fine)
On the more general question is there a shorter syntax when using context bounds type parameters: in general, there is not. It is up to the typeclass to provide some sugar to make it easy to use, as Numeric does here.
For instance, it is more or less customary to have an apply method in the companion object which makes getting the instance a little easier than with implicitly
object Ordering {
def apply[T](implicit ord: Ordering[T]): Ordering[T] = implicitly[Ordering[T]]
}
so that you can get the implicit just with e.g Ordering[Int], rather than implicitly[Ordering[Int]].