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.
Related
I need help understanding this type signature:
def func[A : Ordering : ClassTag](a: A) = ???
I've come up with dummy examples using the type signature above... and also the type signature I'm more familiar with, that I believe is the close to the same thing based on my dummy example, but I can also come up with a toy example where they are clearly not the same.
These two seem similar:
import scala.reflect.ClassTag
// type signature in question
def func1[A : Ordering : ClassTag](elems: A*) =
Array[A](elems: _*).sorted
// my typical type signature
def func2[A <% Ordered[A]](elems: A*)(implicit c: ClassTag[A]) =
Array[A](elems: _*).sorted
Example use:
class BB(val i: Int) extends Ordered[BB] {
def compare(that: BB): Int = that.i - i
override def toString = s"BB(${i})"
}
func1(new BB(33), new BB(100), new BB(-1))
func2(new BB(33), new BB(100), new BB(-1))
Output for each is:
Array[BB] = Array(BB(100), BB(33), BB(-1))
The one edge case I can come up with where they differ... indicating one is not simply syntactic sugar for the other... is the following, where the function has an implicit order for a class that differs from the class's natural sort order.
This example (below) works fine, and implicit val ordering overrides class BB's natural sort order as I (kind of) expected.
def func3[A <% Ordered[A] : ClassTag](elems: A*) = {
// opposite order defined in class BB
implicit val ordering: Ordering[A] =
Ordering.by{ case bb: BB => bb.i }
Array[A](elems: _*).sorted
}
This version (below) give me an error...
def func3[A : Ordering : ClassTag](elems: A*) = {
// opposite order defined in class BB
implicit val ordering: Ordering[A] =
Ordering.by{ case bb: BB => bb.i }
Array[A](elems: _*).sorted
}
error: ambiguous implicit values: both value evidence$1 of type Ordering[A]
and value ordering of type Ordering[A] match expected type
scala.math.Ordering[A]
So based on this... I'm guessing : Ordering sort of converts Ordered[BB] into an implicit val ordering... or something like that? Are there deeper differences that my toy examples fail to reveal?
Thanks in advance.
A : after a type parameter is syntactic sugar for the declaration of implicit parameters. In this case this means that
def func1[A: Ordering: ClassTag](elems: A*) = Array[A](elems: _*).sorted
is the same as
def func1[A](elems: A*)(implicit ordering: Ordering[A], classTag: ClassTag[A]) = Array[A](elems: _*).sorted
On the other hand func2 is declaring a view bound (<%) from A to Ordered. Knowing this the compiler can summon a Ordering[Ordered] that is passed to the sorted method
The reason why the latest version of fun3 is not compiling is because you are providing 2 implicit Ordering[A] in the scope: the one declared as an implicit parameter of fun3 and the implicit val ordering. The compiler doesn't know which one to choose and it complains about it, you should remove one of them to fix it.
Anyway, it is not a good idea to introduce code about specific types in the implementation of these functions. That pattern matching in the creation of the val ordering will fail for any type that is not BB.
If your goal is to define a specific Ordering[BB] you can do that in the companion object of BB and then load it in the implicit scope of the caller function like this
class BB(val i: Int) {
override def toString: String = s"BB(${i})"
}
object BB {
implicit val ordering = Ordering.by[BB, Int](_.i)
val reverseOrdering = Ordering.by[BB, Int](-_.i)
}
Then when you try to order an BB it will pick the implicit ordering by default, but you could always overwrite it by doing
implicit val ord = BB.reverseOrdering
Seq[BB]().sorted
In the following simplest example I have no compile errors:
object App {
def main(args: Array[String]) = {
test[Int]()
}
def test[T <: Int : ClassTag]() = println(implicitly[ClassTag[T]])
}
the program prints Int. But I don't understand why an object of type ClassTag[T] can be found for implicitly[ClassTag[T]] invocation? the only thing I did was to provide generic type argument. Where does the ClassTag[Int] come from?
The : symbol defines a context bound, which means that the compiler has to have an instance of ClassTag[T] in its implicit scope. It's syntactic sugar for the following:
def test[T <: Int]()(implicit $ev: ClassTag[T]) = println(implicitly[ClassTag[T]])
The call to implicitly will then take $ev as the required instance.
But this of course pushes the question a little bit further: where does the $ev (evidence) come from? To quote the Scala documentation (referring to TypeTag, but the same applies to ClassTag):
Given context bound [T: TypeTag], the compiler will simply generate an
implicit parameter of type TypeTag[T] and will rewrite the method to
look like the example with the implicit parameter in the previous
section.
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.
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 improving the Scala support in Querydsl and I encountered the following issue. Here is a code snippet that illustrates the problem :
// framework types
class RelationalPath[T]
class RelationalPathAdapter[T, R <: RelationalPath[T]](p: R) { def someMethod = {} }
// domain types
class User
class QUser extends RelationalPath[User]
implicit def toAdapter[T, R <: RelationalPath[T]](p: R) = new RelationalPathAdapter[T,R](p)
val path = new QUser()
toAdapter(path).someMethod // DOESN'T COMPILE
path.someMethod // DOESN'T COMPILE
How to match a type in a implicit conversion in addition to it's type argument. I can match either separately, but not both.
In this specific case, the following change works:
implicit def toAdapter[T, R <: RelationalPath[T]](p: RelationalPath[T] with R) =
new RelationalPathAdapter[T,R](p)
This is not really an implicit conversion issue, rather a type inference issue. When you call toAdapter(path), there is nothing implicit.
If you pass the type parameter, it works.
toAdapter[User, QUser](path).someMethod
It can even work with an implicit conversion :
(path: RelationalPathAdapter[User, QUser]).someMethod
but of course, this is rather useless.
The proper way to write the implicit is
implicit def toAdapter[T, R[X] <: RelationalPath[X]](p: R[T])
= new RelationalPathAdapter[T, R[T]](p)