I'm trying to do the following code:
def sum(e: { def *(x: Double): Double}) = e * 2.0
Problem is, this doesn't work with any numeric classes:
sum(20.0)
<console>:9: error: type mismatch;
found : Double(10.0)
required: AnyRef{def *(x: Double): Double}
algo(10.0)
sum(10)
<console>:9: error: type mismatch;
found : Int(10)
required: AnyRef{def *(x: Double): Double}
algo(10)
Is there something wrong with my code?
Scala's structural type doesn't require AnyRef.
Certainly, the following method declaration doesn't work as expected.
def sum(e: { def *(x: Double): Double }) = e * 2.0
The reason of that is the above code is interpreted as the followings:
def sum(e: AnyRef { def *(x: Double): Double}) = e * 2.0
If you specify Any explicitly, the code works:
scala> def sum(e: Any { def *(x: Double): Double }) = e * 2.0
sum: (e: Any{def *(x: Double): Double})Double
scala> sum(10.0)
res0: Double = 20.0
Your sum method expects a subtype of AnyRef while Double and other numeric types are subtypes of AnyVal. What you should do instead, is to use the Numeric typeclass.
def sum[E:Numeric](e:E) = {
val n = implicitly[Numeric[E]]
n.toDouble(e) * 2
}
Related
I am getting following error message:
[error] found : AnyVal
[error] required: Int
But Int extends AnyVal [1] so I believe as in Java, Integer can be casted from Object why it's not working in Scala, what I am missing:
[1] final abstract class Int private extends AnyVal
I also tried with a simple example:
val a: AnyVal = 5
def aTob(a: Int): Int = a * 5
aTob(a)
Error:(5, 73) type mismatch;
found : AnyVal
required: Int
But following works:
val a: Any = 5
def aTob(a: Int): Int = a * 5
aTob(a.asInstanceOf[Int])
I don't want to explicitly cast it, but it should be implicit casting.
[Edit:] I also tried with Any
-
Update:
def getValue(dType: String): Any = {
dType.toLowerCase() match {
case "double[3]" =>
10d
case "float" =>
1f
}
val d = getValue("double[3]")
val f = getValue("float")
SomeClass(d, f)
case class SomeClass(val d : Double, val f: Float)
You can use implicit conversion, but it is prone to error because you if you pass e.g. Float like val a: AnyVal = 5.0F you will get ClassCastException:
implicit def anyValToInt(anyVal: AnyVal): Int = anyVal.asInstanceOf[Int]
val a: AnyVal = 5
def aTob(a: Int): Int = a * 5
aTob(a)
Given a type T, is there an idiomatic Scala way to describe the AnyRef equivalent of T (let's call it ARE[T]). For example,
ARE[T <: AnyRef] is T
ARE[T <: AnyVal] is the java.lang.* equivalent of T when one exists or a compilation error when it does not
The purpose of the question is to allow implementing many methods such as:
def foo[A](...): ARE[A]
while avoiding the naive def foo[A <: AnyRef](...): A + overloading for Boolean, Byte, Char, Double, Float, Int, Long and Short.
The standard way to implement a type computation like this is to create a typeclass:
sealed trait Box[T] {
type Out
def apply(t: T): Out
}
object Box {
type Aux[T, ARE] = Box[T] { type Out = ARE }
def make[T, ARE](f: T => ARE): Box.Aux[T, ARE] = new Box[T] {
type Out = ARE
def apply(t: T) = f(t)
}
implicit val int: Box.Aux[Int, java.lang.Integer] = make(Int.box)
implicit val long: Box.Aux[Long, java.lang.Long] = make(Long.box)
implicit val short: Box.Aux[Short, java.lang.Short] = make(Short.box)
implicit val byte: Box.Aux[Byte, java.lang.Byte] = make(Byte.box)
implicit val char: Box.Aux[Char, java.lang.Character] = make(Char.box)
implicit val float: Box.Aux[Float, java.lang.Float] = make(Float.box)
implicit val double: Box.Aux[Double, java.lang.Double] = make(Double.box)
implicit val boolean: Box.Aux[Boolean, java.lang.Boolean] = make(Boolean.box)
implicit val unit: Box.Aux[Unit, scala.runtime.BoxedUnit] = make(Unit.box)
implicit def anyRef[T <: AnyRef]: Box.Aux[T, T] = make(identity)
def box[T](t: T)(implicit are: Box[T]): are.Out = are(t)
}
This can be used like any other typeclass. For example, you can compute the type ARE with the help of Box.Aux in your own functions:
def box2[T, ARE](t: T)(implicit box: Box.Aux[T, ARE]): ARE = box(t)
Scala accepts the output of Box.box when AnyRef is expected:
scala> def foo[T <: AnyRef](anyRef: T): T = anyRef
foo: [T <: AnyRef](anyRef: T)T
scala> foo(10)
<console>:13: error: inferred type arguments [Int] do not conform to method foo's type parameter bounds [T <: AnyRef]
foo(10)
^
<console>:13: error: type mismatch;
found : Int(10)
required: T
foo(10)
^
scala> foo(Box.box(10))
res1: Box.int.Out = 10
And Scala also knows the exact ARE type returned from Box.box:
scala> def bar[T](t: T)(implicit ev: T =:= java.lang.Integer) = ev
bar: [T](t: T)(implicit ev: =:=[T,Integer])=:=[T,Integer]
scala> bar(10)
<console>:13: error: Cannot prove that Int =:= Integer.
bar(10)
^
scala> bar(Box.box(10))
res2: =:=[Box.int.Out,Integer] = <function1>
I have this class:
implicit class Escritor(cv: ContentValues) extends AnyVal {
def pon[T](col: Columna[T], valor: Int) = {
cv.put(col.nombre, valor)
cv
}
def pon[T](col: Columna[T], valor: Long) = {
cv.put(col.nombre, valor)
cv
}
def pon[T](col: Columna[T], valor: Float) = {
cv.put(col.nombre, valor)
cv
}
def pon[T](col: Columna[T], valor: Double) = {
cv.put(col.nombre, valor)
cv
}
def pon[T](col: Columna[T], valor: Date) = {
cv.put(col.nombre, valor.getTime) // getTime returns long
cv
}
}
The ContentValues class has many overloads for the put() method, including:
put(String, Float)
put(String, Double)
put(String, Long)
put(String, Int)
I receive the following error when compiling for the Float, Int, Long and Date version:
Both method put in class ContentValues of type (x$1: String, x$2: Double)Unit
[error] and method put in class ContentValues of type (x$1: String, x$2: Float)Unit
How can the Scala compiler get fooled.
For me, there shoud be no ambiguitiy, because a perfect match can be obtained.
Is this a bug in the Scala compiler or is it by design?
I've read before this blog entry.
Using Scala 2.10.4. I haven't tested with Scala 2.11.0.
Scala does overload resolution by taking the methods that could apply and then choosing the most specific among them.
Numeric widening means that (java.lang.Float) and (java.lang.Double) apply to an int arg, but those boxed java types are not promoted, so neither is deemed more specific. They are apples and oranges.
So this works:
scala> val i: java.lang.Float = 3
i: Float = 3.0
but given
scala> def f(x: java.lang.Double) = x
f: (x: Double)Double
scala> f(3.0f)
res5: Double = 3.0
but
scala> f(new java.lang.Float(3.0f))
<console>:12: error: type mismatch;
found : Float
required: Double
f(new java.lang.Float(3.0f))
^
Yet,
scala> object X { def f(i: java.lang.Integer) = 0 ; def f(j: java.lang.Float) = 0 ; def f(k: java.lang.Double) = 0 }
defined object X
then you can pre-promote:
scala> X f (5: java.lang.Integer)
res8: Int = 0
One possible solution is to use: Float.box(), Long.box() and Int.box().
I know view bounds may be deprecated soon. Please ignore that.
The following code compiles if only one of the last 3 implicit conversions are uncommented. Is this a compiler bug?
object Viewable extends App {
/** Speed of light in m/s */
val C: Double = 299293458d
/** #param weight in kilograms */
case class Matter(name: String, weight: Double) {
/** #return matter-energy equivalence in megajoules */
def energy: Double = weight * C * C / 1000000d
def megaJouleMsg: String = f"$name's mass-energy equivalence is $energy%.0f megajoules."
}
case class Animal(name: String, height: Double, weight: Double)
case class Vegetable(name: String, height: Double, weight: Double)
case class Mineral(name: String, weight: Double)
case class Bug(name: String, height: Double, weight: Double, canFly: Boolean)
case class Whale(name: String, height: Double, weight: Double, hasTeeth: Boolean)
case class AppleTree(name: String, height: Double, weight: Double, age: Int)
case class Grass(name: String, height: Double, weight: Double, edible: Boolean)
case class Sand(name: String, color: String, weight: Double)
case class Rock(name: String, color: String, weight: Double)
implicit def sandToMineral(sand: Sand) = Mineral(sand.name, sand.weight)
implicit def rockToMineral(rock: Rock) = Mineral(rock.name, rock.weight)
implicit def appleTreeToVegetable(tree: AppleTree) = Vegetable(tree.name, tree.height, tree.weight)
implicit def grassToVegetable(grass: Grass) = Vegetable(grass.name, grass.height, grass.weight)
implicit def bugToAnimal(bug: Bug) = Animal(bug.name, bug.height, bug.weight)
implicit def whaleToAnimal(whale: Whale) = Animal(whale.name, whale.height, whale.weight)
implicit def animalToMatter[X <% Animal](animal: X) = Matter(animal.name, animal.weight)
implicit def vegetableToMatter[X <% Vegetable](vegetable: X) = Matter(vegetable.name, vegetable.weight)
implicit def mineralToMatter[X <% Mineral](mineral: X) = Matter(mineral.name, mineral.weight)
println(Animal("Poodle", 1.0, 8.0).megaJouleMsg)
println(AppleTree("Spartan", 2.3, 26.2, 12).megaJouleMsg)
println(Rock("Quartz crystal", "white", 2.3).megaJouleMsg)
}
The error messages are:
type mismatch;
found : solutions.Viewable.Animal
required: ?{def megaJouleMsg: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method animalToMatter in object Viewable of type [X](animal: X)(implicit evidence$1: X => solutions.Viewable.Animal)solutions.Viewable.Matter
and method vegetableToMatter in object Viewable of type [X](vegetable: X)(implicit evidence$2: X => solutions.Viewable.Vegetable)solutions.Viewable.Matter
are possible conversion functions from solutions.Viewable.Animal to ?{def megaJouleMsg: ?}
println(Animal("Poodle", 1.0, 8.0).megaJouleMsg)
^
type mismatch;
found : solutions.Viewable.AppleTree
required: ?{def megaJouleMsg: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method animalToMatter in object Viewable of type [X](animal: X)(implicit evidence$1: X => solutions.Viewable.Animal)solutions.Viewable.Matter
and method vegetableToMatter in object Viewable of type [X](vegetable: X)(implicit evidence$2: X => solutions.Viewable.Vegetable)solutions.Viewable.Matter
are possible conversion functions from solutions.Viewable.AppleTree to ?{def megaJouleMsg: ?}
println(AppleTree("Spartan", 2.3, 26.2, 12).megaJouleMsg)
^
Well the compiler gives the error precisely. This is because there is more than one function which can Animal => Matter. i.e. your below 3 functions:
implicit def animalToMatter[X](animal: X) (implicit ev: X => Animal) = Matter(animal.name, animal.weight)
implicit def vegetableToMatter[X ](vegetable: X) (implicit ev: X => Vegetable) = Matter(vegetable.name, vegetable.weight)
implicit def mineralToMatter[X ](mineral: X) (implicit ev: X => Mineral) = Matter(mineral.name, mineral.weight)
are equally eligible to be called when you do Animal("Poodle", 1.0, 8.0).megaJouleMsg.
When you call megaJouleMsg the compiler looks for any implicit function available that can take Animal and return an object containing method megaJouleMsg (Matter in your case). Now all the 3 functions can take Animal (there is no constraint coded any where) and can return Matter. So the compiler gets confused on which function to calls
Solution: From what it appears, the view bound is not required. This will do:
implicit def animalToMatter(animal: Animal) = Matter(animal.name, animal.weight)
implicit def vegetableToMatter(vegetable: Vegetable) = Matter(vegetable.name, vegetable.weight)
implicit def mineralToMatter(mineral: Mineral) = Matter(mineral.name, mineral.weight)
scala> Animal("Poodle", 1.0, 8.0).megaJouleMsg
res1: String = Poodle's mass-energy equivalence is 716612592013 megajoules.
Edit: Looks like the confusion is because of X <% Animal. In animalToMatter function, it expects an implicit argument which can take X and return Animal. Now if you see in your scope there is no such function X => Animal. But because you are passing Animal("Poodle", 1.0, 8.0) it doesn't need any implicit function because it has already obtained Animal.
In short to repeat the compiler process on seeing Animal("Poodle", 1.0, 8.0).megaJouleMsg:
Sees all functions in the current scope which can take Animal and return Matter.
All the 3 functions can take Animal and return Matter. Note that vegetableToMatter and mineralToMatter will fail if accepted. i.e. though they are eligible but they will not succeed because they dont have any implicit function available that can X => Animal
Throws Error
As an example consider this:
scala> implicit def f[T <% Int](n:T) = Matter("",1)
warning: there were 1 feature warning(s); re-run with -feature for details
f: [T](n: T)(implicit evidence$1: T => Int)Matter
scala> 1.megaJouleMsg
res2: String = 's mass-energy equivalence is 89576574002 megajoules.
scala> "a".megaJouleMsg
<console>:12: error: No implicit view available from String => Int.
"a".megaJouleMsg
^
<console>:12: error: value megaJouleMsg is not a member of String
"a".megaJouleMsg
Notice the error? It gives:
No implicit view available from String => Int.
and not just value megaJouleMsg is not a member of String
Which simply means "a" was eligible for the implicit function f but f could not find a function that could convert it to Int and hence it gives error No implicit view available.... If it was not eligible for function f, then it would just throw error megaJouleMsg is not a member...
I have seen a function named implicitly used in Scala examples. What is it, and how is it used?
Example here:
scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
| implicit def stringImpl = new Foo[String] {
| def apply(list : List[String]) = println("String")
| }
| implicit def intImpl = new Foo[Int] {
| def apply(list : List[Int]) = println("Int")
| }
| } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit
scala> foo(1)
<console>:8: error: type mismatch;
found : Int(1)
required: List[?]
foo(1)
^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
Foo[Double]
foo(List(1.0))
^
Note that we have to write implicitly[Foo[A]].apply(x) since the compiler thinks that implicitly[Foo[A]](x) means that we call implicitly with parameters.
Also see How to investigate objects/types/etc. from Scala REPL? and Where does Scala look for implicits?
implicitly is avaliable in Scala 2.8 and is defined in Predef as:
def implicitly[T](implicit e: T): T = e
It is commonly used to check if an implicit value of type T is available and return it if such is the case.
Simple example from retronym's presentation:
scala> implicit val a = "test" // define an implicit value of type String
a: java.lang.String = test
scala> val b = implicitly[String] // search for an implicit value of type String and assign it to b
b: String = test
scala> val c = implicitly[Int] // search for an implicit value of type Int and assign it to c
<console>:6: error: could not find implicit value for parameter e: Int
val c = implicitly[Int]
^
Here are a few reasons to use the delightfully simple method implicitly.
To understand/troubleshoot Implicit Views
An Implicit View can be triggered when the prefix of a selection (consider for example, the.prefix.selection(args) does not contain a member selection that is applicable to args (even after trying to convert args with Implicit Views). In this case, the compiler looks for implicit members, locally defined in the current or enclosing scopes, inherited, or imported, that are either Functions from the type of that the.prefix to a type with selection defined, or equivalent implicit methods.
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
Implicit Views can also be triggered when an expression does not conform to the Expected Type, as below:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
Here the compiler looks for this function:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
Accessing an Implicit Parameter Introduced by a Context Bound
Implicit parameters are arguably a more important feature of Scala than Implicit Views. They support the type class pattern. The standard library uses this in a few places -- see scala.Ordering and how it is used in SeqLike#sorted. Implicit Parameters are also used to pass Array manifests, and CanBuildFrom instances.
Scala 2.8 allows a shorthand syntax for implicit parameters, called Context Bounds. Briefly, a method with a type parameter A that requires an implicit parameter of type M[A]:
def foo[A](implicit ma: M[A])
can be rewritten as:
def foo[A: M]
But what's the point of passing the implicit parameter but not naming it? How can this be useful when implementing the method foo?
Often, the implicit parameter need not be referred to directly, it will be tunneled through as an implicit argument to another method that is called. If it is needed, you can still retain the terse method signature with the Context Bound, and call implicitly to materialize the value:
def foo[A: M] = {
val ma = implicitly[M[A]]
}
Passing a subset of implicit parameters explicitly
Suppose you are calling a method that pretty prints a person, using a type class based approach:
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
What if we want to change the way that the name is output? We can explicitly call PersonShow, explicitly pass an alternative Show[String], but we want the compiler to pass the Show[Int].
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
Starting Scala 3 implicitly has been replaced with improved summon which has the advantage of being able to return a more precise type than asked for
The summon method corresponds to implicitly in Scala 2. It is
precisely the same as the the method in Shapeless. The difference
between summon (or the) and implicitly is that summon can return a
more precise type than the type that was asked for.
For example given the following type
trait F[In]:
type Out
def f(v: Int): Out
given F[Int] with
type Out = String
def f(v: Int): String = v.toString
implicitly method would summon a term with erased type member Out
scala> implicitly[F[Int]]
val res5: F[Int] = given_F_Int$#7d0e5fbb
scala> implicitly[res5.Out =:= String]
1 |implicitly[res5.Out =:= String]
| ^
| Cannot prove that res5.Out =:= String.
scala> val x: res5.Out = ""
1 |val x: res5.Out = ""
| ^^
| Found: ("" : String)
| Required: res5.Out
In order to recover the type member we would have to refer to it explicitly which defeats the purpose of having the type member instead of type parameter
scala> implicitly[F[Int] { type Out = String }]
val res6: F[Int]{Out = String} = given_F_Int$#7d0e5fbb
scala> implicitly[res6.Out =:= String]
val res7: res6.Out =:= String = generalized constraint
However summon defined as
def summon[T](using inline x: T): x.type = x
does not suffer from this problem
scala> summon[F[Int]]
val res8: given_F_Int.type = given_F_Int$#7d0e5fbb
scala> summon[res8.Out =:= String]
val res9: String =:= String = generalized constraint
scala> val x: res8.Out = ""
val x: res8.Out = ""
where we see type member type Out = String did not get erased even though we only asked for F[Int] and not F[Int] { type Out = String }. This can prove particularly relevant when chaining dependently typed functions:
The type summoned by implicitly has no Out type member. For this
reason, we should avoid implicitly when working with dependently typed
functions.
A "teach you to fish" answer is to use the alphabetic member index currently available in the Scaladoc nightlies. The letters (and the #, for non-alphabetic names) at the top of the package / class pane are links to the index for member names beginning with that letter (across all classes). If you choose I, e.g., you'll find the implicitly entry with one occurrence, in Predef, which you can visit from the link there.