Scala Implicit function within a function call - scala

I've defined a class that has a method in it that is trying to make use of a function with an implicit parameter in it. Unfortunately it's failing to compile
class Test {
def useImplicit(implicit a: Boolean) = a
def getAnswer() = if (useImplicit) println("yes") else println("no")
}
object Preferences {
implicit val yes = false
implicit val no = false
}
The problem is that when I go to compile the class to try and test it out I get the error
could not find implicit value for parameter a: Boolean
def getAnswer() = if (useImplicit) println("yes") else println("no")
I'm not exactly sure what is going on here. The reason for me trying it this way is I am ultimately wanting to overload hashCode and determine at runtime whether I should run my overloaded version or call the parent implementation. If this isn't possible I suppose I could make the class take an implicit

getAnswer is calling useImplicit, but there is no implicit Boolean within the scope of Test. getAnswer will also require the implicit parameter to work:
def getAnswer(implicit a: Boolean) = if(useImplicit) println("yes") else println("no")
The alternative is making Test require the implicit on instantiation, as you say.

Related

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.

'ambiguous reference to overloaded definition' for implicit conversions without Manifest

There's a situation where I get a compiler error for an implicit conversion if I do not include a Manifest:
import scala.language.implicitConversions
abstract class Thing[+A] {
def get:A
}
case class SubThing[+A](a:A) extends Thing[A] {
def get = a
}
object Thing {
implicit def anyToThing[A](a:A):Thing[A] = SubThing(a)
}
object Funcs {
def f(x:Thing[Int]) = x.get + 1
def f(x:Thing[Double]) = x.get + 1.0
}
object Main {
def main(args:Array[String]) = {
println(Funcs.f(1))
}
}
will give
error: ambiguous reference to overloaded definition,
both method f in object Funcs of type (x: Thing[Double])Double
and method f in object Funcs of type (x: Thing[Int])Int
match argument types (Int) and expected result type Any
println(Funcs.f(1))
^
However, if I pass in an implicit Manifest for A in the implicit conversion:
import scala.language.implicitConversions
abstract class Thing[+A] {
def get:A
}
case class SubThing[+A](a:A) extends Thing[A] {
def get = a
}
object Thing {
implicit def anyToThing[A:Manifest](a:A):Thing[A] = SubThing(a)
}
object Funcs {
def f(x:Thing[Int]) = x.get + 1
def f(x:Thing[Double]) = x.get + 1.0
}
object Main {
def main(args:Array[String]) = {
println(Funcs.f(1))
}
}
Causes the code to compile fine. Why is this the case? There's a real example of this in our codebase, which gives a lot of 'no Manifest for T' errors if you're relying on the implicit conversion in generic situations, which are eliminated by creating the wrapper class explicitly; however if we could just get the Manifest out of that implicit conversion that would be ideal. Why is it required, or is there another way to accomplish the same thing while avoiding Manifests?
This was caused by scala's automatic promotion of Ints to Double, which made the implicit conversion ambiguous. When the manifest is included, it creates an implicit parameter that causes the function resolution to become unambiguous, just as DummyImplicit implicit parameters are used to combat overloaded-function ambiguity that's due to the type erasure as Ivan mentioned.
I believe this happens because once converted to Thing, type erasure kicks in and its no longer a Thing[Int] or Thing[Double] but a Thing[_] and hence the following method overloading does not work.
object Funcs {
def f(x:Thing[Int]) = x.get + 1
def f(x:Thing[Double]) = x.get + 1.0
}
The manifest is where my understanding breaks down a little because I have never dealt with it much, but I guess it presevies the type so that the method overloading works.
You could work around this with macros I believe, although that would preclude calling Funcs.f() on anything the compiler didnt know for sure was an Int or Double.

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.

Is it possible to write a method in Scala returning objects with different type parameter?

Is it possible to write a method in Scala which returns an object of a type-parameterized class with different type paramter ? Something like this:
class A[T]
def f(switch: Boolean): A = if(switch) new A[Int] else new A[String]
Please note: The Code above is fictional to show the type of problem; The code above does not make semantically sense.
The code above will not compile because return type A is not parameterized.
You can, and you can even do it with type-safety with the aid of implicit arguments that encapsulate the pairings:
class TypeMapping[+A,B] {
def newListB = List.empty[B]
}
trait Logical
object True extends Logical
object False extends Logical
implicit val mapFalseToInt = new TypeMapping[False.type,Int]
implicit val mapTrueToString = new TypeMapping[True.type,String]
def f[A <: Logical,B](switch: A)(implicit tmap: TypeMapping[A,B]) = tmap.newListB
scala> f(True)
res2: List[String] = List()
scala> f(False)
res3: List[Int] = List()
You do have to explicitly map from boolean values to the custom True and False values.
(I have chosen List as the target class just as an example; you could pick anything or even make it generic with a little more work.)
(Edit: as oxbow_lakes points out, if you need all possible return values to be represented on the same code path, then this alone won't do it, because the superclass of List[Int] and List[String] is List[Any], which isn't much help. In that case, you should use an Either. My solution is for a single function that will be used only in the True or False contexts, and can maintain the type information there.)
One way of expressing this would be by using Either;
def f(switch: Boolean) = if (switch) Left(new A[Int]) else Right(newA[String])
This of course returns an Either[A[Int], A[String]]. You certainly cannot (at the moment) declare a method which returns some parameterized type P, with some subset of type parameters (i.e. only Int or String).
The language ceylon has union types and I understand the intention is to add these to scala in the near future, in which case, you could define a method:
def f(switch: Boolean): A[Int|String] = ...
Well, you could do something like that.
scala> class A {
| type T
| }
defined class A
scala> def f(b: Boolean): A = if(b) new A { type T = Int } else new A { type T = String }
f: (b: Boolean)A
But this is pointless. Types are a compile time information, and that information is getting lost here.
How about an absolutely minimal change to the "fictional code"? If we just add [_] after the "fictional" return type, the code will compile:
class A[T]
def f(switch: Boolean):A[_] = if(switch) new A[Int] else new A[String]
It is worth noting that A[_] is not the same as A[Any]. A[T] does not need to be defined covariant for the code to compile.
Unfortunately, information about the type gets lost.