can scala implicit convert from `Long` to `AnyRef` [duplicate] - scala

This question already has answers here:
Result type of an implicit conversion must be more specific than AnyRef
(4 answers)
Closed 4 years ago.
def testLong(v: Any): Unit = {
println(v.getClass) // print: class java.lang.Long
}
testLong(103L) // compile passed
from last snippet, it shows that the variable v is class java.lang.Long.And it's a subclass of java.lang.Object.
We also know from the scala Unified types system the AnyRef is equals to java.lang.Object type. But why it compile failed as follows:
def testLong(v: AnyRef): Unit = {
println(v.getClass)
}
testLong(103L) // compile failed

Probably the reason why the implicit conversion was not used in the second example is because this:
// val l: AnyRef = 10L
// error: the result type of an implicit conversion must be more specific than AnyRef.
This answer may explain welll why this happens.
However, you can re-write your method for make it work using an implicit evidence.
def testLong[T](v: T)(implicit ev: T => AnyRef): Unit = {
println(v.getClass)
}
testLong(10L)
// class java.lang.Long
Curious enough, if you make the method specific to Long only, the printed class changes.
def testLong(v: Long)(implicit ev: Long => AnyRef): Unit = {
println(v.getClass)
}
testLong(10L)
// long

Related

How do I match types that don't have a specific typeclass instance? [duplicate]

This question already has answers here:
Using context bounds "negatively" to ensure type class instance is absent from scope
(2 answers)
Closed 6 years ago.
I would like to define some behavior for those types that don't have an instance for a certain typeclass:
// Given
trait SomeTypeclass[T]
// when we have implicit SomeTypeclass[T]
def f[T: SomeTypeclass](x:T):Unit = ???
// when we don't have instance
def f[T !: SomeTypeclass](x: T):Unit = ???
We could handle the difference within the typeclass but then I would need to create extra instances just to support some generic behavior.
Is there a way to negate a type bound? A way to make the function with !: compile?
(I would like to do this in vanilla Scala, without scalaz, shapeless, etc)
Is there a way to negate a type bound?
No! The syntax [T: SomeTypeclass] is just shorthand for (implicit val t: Sometypeclass[T]), and there is no way to "negate" that. You could overload the method but that would create an ambiguity.
But you can "nest" type classes.
trait ExistsLowPri {
implicit def no[A]: Exists[A] = Exists.No
}
object Exists extends ExistsLowPri {
case class Yes[A](peer: A) extends Exists[A]
case object No extends Exists[Nothing]
implicit def yes[A](implicit peer: A): Exists[A] = new Yes(peer)
}
sealed trait Exists[+A]
Example:
trait Show[-A] {
def show(x: A): String
}
def test[A](x: A)(implicit ex: Exists[Show[A]]): Unit = println(
ex match {
case Exists.Yes(s) => s.show(x)
case Exists.No => "(no string repr)"
}
)
implicit object ShowBoolean extends Show[Boolean] {
def show(b: Boolean) = if (b) "T" else "F"
}
test(123) // (no string repr)
test(true) // T
However, I would strongly advise against doing this, because the main point of implicits and type classes is to have explicit compiler failure if something is not in scope. This way you will always be able to compile but have no guarantee that you correctly brought a specific type class into scope.
You can roll your own:
trait NoInstance[T[_], A]
object NoInstance extends LowPriorityNoInstance {
implicit def hasInstance0[T[_], A](implicit inst: T[A]): NoInstance[T, A] = ???
implicit def hasInstance1[T[_], A](implicit inst: T[A]): NoInstance[T, A] = ???
}
class LowPriorityNoInstance {
implicit def noInstance[T[_], A]: NoInstance[T, A] = new NoInstance[T, A] {}
}
And then:
scala> implicitly[NoInstance[Ordering, List[Int]]]
res4: NoInstance[Ordering,List[Int]] = LowPriorityNoInstance$$anon$1#5e1fc2aa
scala> implicitly[NoInstance[Ordering, Int]]
<console>:14: error: ambiguous implicit values:
both method hasInstance0 in object NoInstance of type [T[_], A](implicit inst: T[A])NoInstance[T,A]
and method hasInstance1 in object NoInstance of type [T[_], A](implicit inst: T[A])NoInstance[T,A]
match expected type NoInstance[Ordering,Int]
implicitly[NoInstance[Ordering, Int]]
^
In many cases you can avoid this kind of thing with the null default implicit parameter trick, though:
def f[T](x: T)(implicit stc: SomeTypeclass[T] = null): Unit = Option(stc) match {
case Some(instance) => // do something in the case where we have an instance
case None => // do something in the case where we don't have an instance
}
This feels like a hack, but it works and people use it all the time.

Could not find implicit parameter in companion class

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.

What is the implicit resolution sequence in this "simple" ScalaZ tutorial code example?

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.

Scala inference : fail on 1 evaluation, success with intermediate val

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.

Java SortedMap to Scala TreeMap

I'm having trouble converting a java SortedMap into a scala TreeMap. The SortedMap comes from deserialization and needs to be converted into a scala structure before being used.
Some background, for the curious, is that the serialized structure is written through XStream and on desializing I register a converter that says anything that can be assigned to SortedMap[Comparable[_],_] should be given to me. So my convert method gets called and is given an Object that I can safely cast because I know it's of type SortedMap[Comparable[_],_]. That's where it gets interesting. Here's some sample code that might help explain it.
// a conversion from comparable to ordering
scala> implicit def comparable2ordering[A <: Comparable[A]](x: A): Ordering[A] = new Ordering[A] {
| def compare(x: A, y: A) = x.compareTo(y)
| }
comparable2ordering: [A <: java.lang.Comparable[A]](x: A)Ordering[A]
// jm is how I see the map in the converter. Just as an object. I know the key
// is of type Comparable[_]
scala> val jm : Object = new java.util.TreeMap[Comparable[_], String]()
jm: java.lang.Object = {}
// It's safe to cast as the converter only gets called for SortedMap[Comparable[_],_]
scala> val b = jm.asInstanceOf[java.util.SortedMap[Comparable[_],_]]
b: java.util.SortedMap[java.lang.Comparable[_], _] = {}
// Now I want to convert this to a tree map
scala> collection.immutable.TreeMap() ++ (for(k <- b.keySet) yield { (k, b.get(k)) })
<console>:15: error: diverging implicit expansion for type Ordering[A]
starting with method Tuple9 in object Ordering
collection.immutable.TreeMap() ++ (for(k <- b.keySet) yield { (k, b.get(k)) })
Firstly, to clarify your error:
// The type inferencer can't guess what you mean, you need to provide type arguments.
// new collection.immutable.TreeMap
// <console>:8: error: diverging implicit expansion for type Ordering[A]
//starting with method Tuple9 in object Ordering
// new collection.immutable.TreeMap
// ^
You can write an implicit to treat Comparable[T] as Ordering[T] as follows.
// This implicit only needs the type parameter.
implicit def comparable2ordering[A <: Comparable[A]]: Ordering[A] = new Ordering[A] {
def compare(x: A, y: A) = x.compareTo(y)
}
trait T extends Comparable[T]
implicitly[Ordering[T]]
However, if you really don't know the type of the key, I don't think you can create the Ordering in terms of Comparable#compareTo, at least without reflection:
val comparableOrdering = new Ordering[AnyRef] {
def compare(a: AnyRef, b: AnyRef) = {
val m = classOf[Comparable[_]].getMethod("compareTo", classOf[Object])
m.invoke(a, b).asInstanceOf[Int]
}
}
new collection.immutable.TreeMap[AnyRef, AnyRef]()(comparableOrdering)
You can probably also just give an explicit type to the TreeMap. That's how I just solved a similar problem:
collection.immutable.TreeMap[whatever,whatever]() ++ ...
(Sorry, I don't have the time to check how exactly this applies to the sources posted in the question.)