I have a Number Wrapper like this
class NumWrapper[A<:AnyVal](var v: A)(implicit n:Numeric[A]) {
def +(other: A): NumWrapper[A] = {
new NumWrapper(n.plus(v, other))
}
def -(other: A): NumWrapper[A] = {
new NumWrapper(n.minus(v, other))
}
}
All work fine. But when I want to have the implicit conversion, i create a companion class as followed:
object NumWrapper {
implicit def toNumWrapper[A<:AnyVal](v: A) = new NumWrapper[A](v)
}
But I have the error at compilation:
could not find implicit value for parameter n: Numeric[A]
What is wrong here ? Why it is trying to find the implicit match for type A at compilation?
Thank you very much for your help.
Implicit checks in Scala are performed at compile time (it is a statically typed language). If the compiler can't identify a single, unambiguous, matching implicit value that will be available at the calling location, it complains.
One way you can fix this here is to add the implicit requirement to the toNumWrapper method:
object NumWrapper {
implicit def toNumWrapper[A<:AnyVal](v: A)(implicit n:Numeric[A]) = new NumWrapper[A](v)
}
This pushes the requirment for an implicit Numeric out to the location where the implicit conversion is required, eg, in the console, I could then write:
scala> val chk1 = 3L
chk1: Long = 3
scala> val chk2 = NumWrapper.toNumWrapper(chk1)
chk2: NumWrapper[Long] = NumWrapper#1e89017a
And the compiler is happy because (I think - not entirely sure of this) the Long value carries its own implicit Numeric[Long] with it.
According your code,
class NumWrapper[A<:AnyVal](var v: A)(implicit n:Numeric[A])
to call new NumWrapper[MyType](v) a Numeric[MyType] must be in the scope of implicit resolution.
So when you have
object NumWrapper {
implicit def toNumWrapper[A<:AnyVal](v: A) = new NumWrapper[A](v)
}
which is calling this NumWrapper constructor, the Numeric[A] must resolved. That's not the case and the compiler raise the mentioned error.
Related
The code snippet below is taken from this ScalaZ tutorial.
I cannot figure out how the implicit resolution rules are applied when evaluating 10.truthy at the bottom of the code example.
Things that - I think - I do understand are the following:
1) The implicit value intCanTruthy is an instance of an anonymous subclass of CanTruthy[A] which defines the truthys method for Int-s according to :
scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
case 0 => false
case _ => true
})
intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1#71780051
2) The toCanIsTruthyOps implicit conversion method is in scope when evaluating 10.truthy, so the compiler will try to use this implicit conversion method when it sees that Int does not have a truthy method. So the compiler will try to look for some implicit conversion method which converts 10 into an object that does have a truthy method and therefor it will try toCanIsTruthyOps to this conversion that.
3) I suspect that the implicit value intCanTruthy somehow might be used when the compiler tries the toCanIsTruthyOps implicit conversion on 10.
But this is where I really get lost. I just don't see how the implicit resolution process proceeds after this. What happens next ? How and Why ?
In other words, I don't know what is the implicit resolution sequence that allows the compiler to find the implementation of the truthy method when evaluating 10.truthy.
Questions:
How will 10 be converted to some object which does have the correct truthy method ?
What will that object be ?
Where will that object come from?
Could someone please explain, in detail, how the implicit resolution takes place when evaluating 10.truthy ?
How does the self-type { self => ... in CanTruthy play a role in the implicit resolution process ?
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait CanTruthy[A] { self =>
/** #return true, if `a` is truthy. */
def truthys(a: A): Boolean
}
object CanTruthy {
def apply[A](implicit ev: CanTruthy[A]): CanTruthy[A] = ev
def truthys[A](f: A => Boolean): CanTruthy[A] = new CanTruthy[A] {
def truthys(a: A): Boolean = f(a)
}
}
trait CanTruthyOps[A] {
def self: A
implicit def F: CanTruthy[A]
final def truthy: Boolean = F.truthys(self)
}
object ToCanIsTruthyOps {
implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A]) =
new CanTruthyOps[A] {
def self = v
implicit def F: CanTruthy[A] = ev
}
}
// Exiting paste mode, now interpreting.
defined trait CanTruthy
defined module CanTruthy
defined trait CanTruthyOps
defined module ToCanIsTruthyOps
Trying out the type class on 10 :
scala> import ToCanIsTruthyOps._
import ToCanIsTruthyOps._
scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
case 0 => false
case _ => true
})
intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1#71780051
scala> 10.truthy
res6: Boolean = true
First of all, thanks for pasting a fully self-contained example.
How will 10 be converted to some object which does have the correct truthy method ?
When calling a method on a value whose type A does not supply that method, an implicit conversion must kick in, i.e. there must be a method or function in scope with signature A => B with B having the method in question (truthy). In the case of a conversion method, it may ask for additional implicit parameters which would be looked up accordingly.
The conversion method is toCanIsTruthyOps, made available by importing the contents of ToCanIsTruthyOps. The type B in the aforementioned sentence then is CanTruthyOps, and the conversion method is toCanIsTruthyOps. It may be invoked by the compiler as long as the implicit type-class evidence parameter CanTruthy is found. So since type A = Int, the compiler has to find an implicit value of type CanTruthy[Int] if the call 10.truthy is going to be successful.
It looks for such a value in several places. It could be in the companion object of Int (that doesn't exist) or the companion object of CanTruthy, or it was explicitly imported into the current scope. Here, the last case is used. You explicitly created the implicit value intCanTruthy, and that value is now found. And that's it.
What will that object be ?
There will be a temporary instance of CanTruthyOps whose mere purpose is to call truthys on the evidence type class value (your intCanTruthy here).
Where will that object come from?
It is found in the look-up for implicit conversions Int => CanTruthyOps[Int]. The conversion performs the instantiation of that object.
Could someone please explain, in detail, how the implicit resolution takes place when evaluating 10.truthy ?
See answer to first question above. Or as explicit code:
type A = Int
val v: A = 10
val ev: CanTruthy[A] = intCanTruthy
val ops: CanTruthyOps[A] = ToCanIsTruthyOps.toCanIsTruthyOps(v)(ev)
ops.truthy
How does the self-type { self => ... in CanTruthy play a role in the implicit resolution process ?
It has nothing to do with the implicit resolution. Indeed, in your example of the trait CanTruthy, the self acts as an alias for this and isn't even used, so you could just remove it.
The signature of the method that converts any A to CanTruthyOps[T] which has the truthy method is:
implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A])
this means that it doesn't convert just any A but only those for which there is a CanTruthy[A] defined, which is what the implicit ev parameter is for. This means that, as part of the process of mapping 10 to something that has a .truthy method, also intCanTruthy is looked up before the wrapping is done. So by the time that 10 has been implicitly converted to something with a truthy method, the intCanTruthy instance will have already been looked up and stored away as the F attribute of the CanTruthyOps:
implicit def F: CanTruthy[A] = ev
(actually I don't know why that implicit is necessary there; truthy() will turn to F explicitly.
F.truthys(self)
As to how exactly implicit resolution works, you're better off looking up documentation that describes the process in detail.
I'm beginner in scala and don't understand what happend here :
Given :
val reverse:Option[MyObject] = ...
And myObject.isNaire return Boolean.
If I do :
val v:Option[Boolean] = reverse.map(_.isNaire)
val b:Boolean = v.getOrElse(false)
It work.
Now, If I do :
val b:Boolean = reverse.map(_.isNaire).getOrElse(false)
It fail to compile with a type mismatch: found Any, required Boolean
Edit : Thanks Beryllium, by making SSCCE, I found a beginning of explication. In the first example, myObject is a java class, so isNaire is a java.lang.Boolean. I thought implicit conversion should make this transparent so the explanation is still welcome.
class Test(val naire:java.lang.Boolean)
class Other {
val testValue = Some(new Test(true))
def mysteriousCompilationError:Boolean = testValue.map(_.naire).getOrElse(false)
}
Note: ScalaCompiler is 2.10.2
In the scala.Predef there's an implicit conversion from java.lang.Boolean to scala.Boolean:
implicit def Boolean2boolean(x: java.lang.Boolean): Boolean = x.booleanValue
So in your first case val v:Option[Boolean] = reverse.map(_.isNaire) the compiler see's a java.lang.Boolean and looks for an implicit method in scope to convert it to a scala.Boolean, which it conveniently finds in scala.Predef.
In you're second case, testValue.map(_.naire).getOrElse(false), the compiler is doing things in this order:
Option[Test] => Option[java.lang.Boolean]
getOrElse[B >: A](default: => B): B where A is java.lang.Boolean and B is Any since scala.Boolean is not >: java.lang.Boolean
val b:Boolean, compiler can't find an implicit conversion from Any to scala.Boolean
The only way to get around this, is to tell the compiler during the map operation to use the implicit conversion from scala.Predef to go from java.lang.Boolean to scala.Boolean:
def works:Boolean = testValue.map[Boolean](_.naire).getOrElse(false)
This is a common problem and pops up often since map followed by getOrElse is very convienent. To properly fix this without the extra types, use a fold (catamorphism) over the option:
def worksToo:Boolean = testValue.fold(false)(_.naire)
By using fold you get some added type safety since there's no conversion down to common types. For instance, you can't do this:
def failsTypeCheck = testValue.fold("test")(_.naire)
While the compiler has no problem with this:
def passesTypeCheck = testValue.map(_.naire).getOrElse("test")
java.lang.Boolean and scala.Boolean is not the same. To bridge the gap you have to provide a location where the implicit conversion can do it's work.
There are some patterns to handle these types of Java/Scala interoperability problems:
If it's OK to have a different method to be used from the Scala side, you could use an implicit value class:
object Container {
implicit class Test2Scala(val test: Test) extends AnyVal {
def naireForScala: Boolean = test.naire
}
}
class Other {
val testValue = Some(new Test(true))
import Container._
def mysteriousCompilationError: Boolean =
testValue.map(_.naireForScala).getOrElse(false)
}
This does not require additional instances at run-time. It just provides another method to enrich the Java class.
If you can derive a sub class, you could preserve the method's name by using a DummyImplicit:
class Test2(_naire: Boolean) extends Test(_naire) {
def naire(implicit di: DummyImplicit): Boolean = _naire
}
class Other {
val testValue = Some(new Test2(true))
def mysteriousCompilationError: Boolean =
testValue.map(_.naire).getOrElse(false)
}
The DummyImplicit is required to get a different method signature. It's a bit tricky, requires an additional instance at run-time, but Test2 is a Test (in terms of OOP).
Wrap the Java instance in a Scala instance:
class TestWrapper(test: Test) {
def naire: Boolean = test.naire
}
class Other {
val testValue = Some(new TestWrapper(new Test(true)))
def mysteriousCompilationError: Boolean =
testValue.map(_.naire).getOrElse(false)
}
Requires an additional instance, you have to add delegates, TestWrapper is not a Test, but it's simple.
How would one encode the following constraint in Scala (pseudocode)?
def foo(x: T forSome { type T has a Numeric[T] instance in scope }) = {
val n= implicitly[...] // obtain the Numeric instance for x
n.negate(x) // and use it with x
}
In words: I need a type class instance for my input argument, but I don't care about the argument's type, I just need to obtain the instance and use it on my argument.
It doesn't have to be an existential type, but I need to avoid type parameters in the def's signature.
Edit: just to clarify, the standard approach in these cases, i.e.:
def foo[T: Numeric](x: T) = ...
doesn't work for me, as it requires the addition of a type parameter on the method.
Thanks.
I managed to make it work like this:
implicit class InstanceWithNumeric[T](val inst: T)(implicit val n: Numeric[T])
def foo(iwn: InstanceWithNumeric[_]) {
def genFoo[T](iwn: InstanceWithNumeric[T]) {
println(iwn.n.negate(iwn.inst))
}
genFoo(iwn)
}
And now:
scala> foo(1)
-1
scala> foo(1.2)
-1.2
Not the prettiest, but seems to work.
EDIT: You can avoid defining inner function like this:
implicit class InstanceWithNumeric[T](val inst: T)(implicit val n: Numeric[T]) {
def negate = n.negate(inst)
}
Also, if you want to make implicit conversion to InstanceWithNumeric globally visible, you can do something like this:
class InstanceWithNumeric[T](val inst: T)(implicit val n: Numeric[T])
object InstanceWithNumeric {
implicit def apply[T: Numeric](inst: T) =
new InstanceWithNumeric(inst)
}
If you want to understand how this works, read about so called implicit scope (this question seems to contain good explanation).
Not quite sure what you are attempting, because it seems you need a type once you make the call to implicitly. Would the following work for you?
def foo(implicit x: Numeric[_]) {
//code goes here.
}
Here is a reduced example of what I want to do. The line commented out doesn't compile.
class Animal
object Animal { implicit def toElephant(a: Animal) = a.asInstanceOf[Elephant] }
class Elephant extends Animal
object Main {
def main(args: Array[String]) = {
val a: List[Animal] = List(new Elephant, new Elephant)
// val e: List[Elephant] = a
}
}
In a regular situation, e = a is of course illegal. But with the implicit function, one could think that scala would automatically convert every element in the list.
Is there an elegant way to get this behaviour? If yes, how?
What I wish to know is if there is some obscure corner of scala that can force the behaviour I wish. I am not interested in solutions that add cruft. I can think of them myself. For instance, one could do:
object Animal {
implicit def toElephant(a: Animal) = a.asInstanceOf[Elephant]
implicit def toElephant(a: List[Animal]) = a.asInstanceOf[List[Elephant]] }
and the code above would work.
You can forget implicits and mapping and use simply
val e = a.asInstanceOf[List[Elephant]]
BUT, if you insist, you can of course also do this conversion implicitly. Having an implicit from List[A] to List[B] is no more crufty than an implicit A => B. I wouldn't do this, but if I did I'd generalise it for re-use, importing locally to limit the implicit's scope:
object Implicits {
implicit def AListToBList[A, B <: A](lst: List[A]) = lst.asInstanceOf[List[B]]
}
Then at use-site
import Implicits._
val a: List[Animal] = List(new Elephant, new Elephant)
val e: List[Elephant] = a
e.head.doSomethingElephanty
Be aware of the scope of the import, and stick things within a locally block if necessary.
But with the implicit function, one could think that scala would
automatically convert every element in the list.
Why?
Let's try something:
class X[T : Manifest] {
override def toString = manifest[T].toString
}
val x = new X[Animal]
How will an implicit that converts Animal into Elephant help convert an X[Animal] into an X[Elephant]? There isn't even an instance of Animal to be converted! But let's put an instance there:
class X[T : Manifest](t: T) {
override def toString = manifest[T].toString + t.toString
}
Now we have an instance, but, again, how will Scala convert an X[Animal] into an X[Elephant]? It can't even get at t, because it is private. Let's make it public, then:
class X[T : Manifest](val t: T) {
override def toString = manifest[T].toString + t.toString
}
There, it is public. But how would it be converted? One way would be this:
new X[Elephant](Animal toElephant x.t)
But how would Scala know to do that? Who says that's valid code, or that it is enough?
One could write an implicit teaching X how to convert itself if another implicit conversion is present, and an implicit like that could exist for List, but implicit conversions are dangerous. The less of them there are, the better. And, therefore, such an implicit does not exist.
What about map?
val e = a map {_.asInstanceOf[Elephant]}
or even better:
val e = a collect {case e: Elephant => e}
Note that both asInstanceOf and an implicit conversion for super-type to sub-type is not very ellegant.
I have this bit of code, which works:
val directions = rs.map(_.direction) // Direction extends Enumeration
directions == directions.sorted.reverse
I'd like to instead do something like this:
ratings.map(_.direction).isInBackwardsOrder
class RichSeq[T](seq: Seq[T]) {
def isInBackwardsOrder = seq == seq.sorted.reverse
}
object RichSeq {
implicit def seq2richSeq[T](seq: Seq[T]) = new RichSeq[T](seq)
}
I keep getting the following compilation error:
could not find implicit value for parameter ord: Ordering[T]
def isInBackwardsOrder = seq == seq.sorted.reverse
What I don't understand is why it could find the implicit value for parameter ord, when it was in the original form, but cannot find it once I pull it into a utility class.
Thanks for the help,
Alex
In the original form, you had no generics. directions is a Seq[SomeWellKnownType], and at compile time, the compiler looks for an Ordering[SomeWellKnownType] in implicit scope, and finds one.
On the other hand, in RichSeq[T], the compiler must find an implicit Ordering[T] where T is a type parameter. No way to do that. You must ensure that the Ordering will be available when you create the RichSeq :
class RichSeq[T](seq: Seq[T])(implicit ev: Ordering[T]) {...
There is a shortcut for that, especially if you just need ev in implicit scope without refrencing it explicitly, as in here :
class RichSeq[T : Ordering](seq: Seq[T]) {...
Then you have the exact same problem in your implicit method, which is generic too, with the same solution :
implicit def seq2richSeq[T: Ordering](seq: Seq[T]) = new RichSeq[T](seq)
Then it should work. The seq2richSeq implicit conversion will kick in when an Ordering is available for the type of the elements in the Seq.