Scala: recognising objects of value classes - scala

I'm reflectively invoking a method whose argument might or might not be an instance of a value class. As the purpose of value classes is to avoid boxing of underlying value, if the parameter type is value class then the method in question will in fact expect unboxed value. To handle this case I'm trying to unwrap the underlying value from value class. I first need to determine if the argument is of a value class, and here I hit the first stumbling block:
def isObjectOfValueClass(arg: Any) =
classOf[AnyVal].isAssignableFrom(arg.getClass)
This doesn't work as expected, as the method returns true for:
case class NonValueClass(underlying: Int)
How can isObjectOfValueClass be implemented? Or is there a simpler way to reflectively invoke a method that might take object of a value class as an argument?

First, note that your isObjectOfValueClass will get a boxed version of your value class instances.
Second, it cannot work like you want. It's because classOf[AnyVal] == classOf[AnyRef] == <java.lang.Object>.
There's no runtime way to distinguish between a boxed value class and a reference class (Any doesn't have .instanceOf[T], AnyVal cannot be used in pattern matching or as parameter of .instanceOf[T], and what's most important, compiled value classes do not extend or implement AnyVal).
If you want it decided on compile time, then try:
case class IsAnyVal[-T](val value: Boolean) extends AnyVal
implicit def _noClueHowToNameThisImplicit_1 = IsAnyVal[AnyVal](true)
implicit def _noClueHowToNameThisImplicit_2 = IsAnyVal[AnyRef](false)
def isAnyVal[T](arg: T)(implicit ev: IsAnyVal[T]) = ev.value
scala> isAnyVal(1)
res4: Boolean = true
scala> isAnyVal("")
res5: Boolean = false
I'm not sure how you want to extract the sole field of the detected boxed value class instances without more accidental boxing. Besides, Hotspot is pretty good at optimizing small short-lived objects.

Related

Scala: Type parameters and inheritance

I'm seeing something I do not understand. I have a hierarchy of (say) Vehicles, a corresponding hierarchy of VehicalReaders, and a VehicleReader object with apply methods:
abstract class VehicleReader[T <: Vehicle] {
...
object VehicleReader {
def apply[T <: Vehicle](vehicleId: Int): VehicleReader[T] = apply(vehicleType(vehicleId))
def apply[T <: Vehicle](vehicleType VehicleType): VehicleReader[T] = vehicleType match {
case VehicleType.Car => new CarReader().asInstanceOf[VehicleReader[T]]
...
Note that when you have more than one apply method, you must specify the return type. I have no issues when there is no need to specify the return type.
The cast (.asInstanceOf[VehicleReader[T]]) is the reason for the question - without it the result is compile errors like:
type mismatch;
found : CarReader
required: VehicleReader[T]
case VehicleType.Car => new CarReader()
^
Related questions:
Why cannot the compiler see a CarReader as a VehicleReader[T]?
What is the proper type parameter and return type to use in this situation?
I suspect the root cause here is that VehicleReader is invariant on its type parameter, but making it covariant does not change the result.
I feel like this should be rather simple (i.e., this is easy to accomplish in Java with wildcards).
The problem has a very simple cause and really doesn't have anything to do with variance. Consider even more simple example:
object Example {
def gimmeAListOf[T]: List[T] = List[Int](10)
}
This snippet captures the main idea of your code. But it is incorrect:
val list = Example.gimmeAListOf[String]
What will be the type of list? We asked gimmeAListOf method specifically for List[String], however, it always returns List[Int](10). Clearly, this is an error.
So, to put it in words, when the method has a signature like method[T]: Example[T] it really declares: "for any type T you give me I will return an instance of Example[T]". Such types are sometimes called 'universally quantified', or simply 'universal'.
However, this is not your case: your function returns specific instances of VehicleReader[T] depending on the value of its parameter, e.g. CarReader (which, I presume, extends VehicleReader[Car]). Suppose I wrote something like:
class House extends Vehicle
val reader = VehicleReader[House](VehicleType.Car)
val house: House = reader.read() // Assuming there is a method VehicleReader[T].read(): T
The compiler will happily compile this, but I will get ClassCastException when this code is executed.
There are two possible fixes for this situation available. First, you can use existential (or existentially quantified) type, which can be though as a more powerful version of Java wildcards:
def apply(vehicleType: VehicleType): VehicleReader[_] = ...
Signature for this function basically reads "you give me a VehicleType and I return to you an instance of VehicleReader for some type". You will have an object of type VehicleReader[_]; you cannot say anything about type of its parameter except that this type exists, that's why such types are called existential.
def apply(vehicleType: VehicleType): VehicleReader[T] forSome {type T} = ...
This is an equivalent definition and it is probably more clear from it why these types have such properties - T type is hidden inside parameter, so you don't know anything about it but that it does exist.
But due to this property of existentials you cannot really obtain any information about real type parameters. You cannot get, say, VehicleReader[Car] out of VehicleReader[_] except via direct cast with asInstanceOf, which is dangerous, unless you store a TypeTag/ClassTag for type parameter in VehicleReader and check it before the cast. This is sometimes (in fact, most of time) unwieldy.
That's where the second option comes to the rescue. There is a clear correspondence between VehicleType and VehicleReader[T] in your code, i.e. when you have specific instance of VehicleType you definitely know concrete T in VehicleReader[T] signature:
VehicleType.Car -> CarReader (<: VehicleReader[Car])
VehicleType.Truck -> TruckReader (<: VehicleReader[Truck])
and so on.
Because of this it makes sense to add type parameter to VehicleType. In this case your method will look like
def apply[T <: Vehicle](vehicleType: VehicleType[T]): VehicleReader[T] = ...
Now input type and output type are directly connected, and the user of this method will be forced to provide a correct instance of VehicleType[T] for that T he wants. This rules out the runtime error I have mentioned earlier.
You will still need asInstanceOf cast though. To avoid casting completely you will have to move VehicleReader instantiation code (e.g. yours new CarReader()) to VehicleType, because the only place where you know real value of VehicleType[T] type parameter is where instances of this type are constructed:
sealed trait VehicleType[T <: Vehicle] {
def newReader: VehicleReader[T]
}
object VehicleType {
case object Car extends VehicleType[Car] {
def newReader = new CarReader
}
// ... and so on
}
Then VehicleReader factory method will then look very clean and be completely typesafe:
object VehicleReader {
def apply[T <: Vehicle](vehicleType: VehicleType[T]) = vehicleType.newReader
}

Gap in the concept of implicit Ordering of a type used to create a Collection

Forgive me if the solution to this problem is too obvious or has been resolved already in this forum earlier (in which case, please point me to the post).
I have a class
org.personal.exercises.LengthContentsPair (l: Int, c: String)
{
val length = l
val contents = c
}
Then, in the same source file, I also define an implicit value which defines the way objects
of this type is to be ordered, thus:
object LengthContentsPair {
implicit val lengthContentsPairOrdering = new Ordering [LengthContentsPair] {
def compare (a: LengthContentsPair, b: LengthContentsPair)= {
a.length compare b.length;
}
}
}
following solutions given in this forum.
Now, I want to create a specialized Set which limits the number of elements in the Set to a given number. So, I define a separate class like this:
import scala.collection.immutable.TreeSet;
import org.personal.exercises.LengthContentsPair.lengthContentsPairOrdering;
class FixedSizedSortedSet [LengthContentsPair] extends TreeSet [LengthContentsPair]
{ ..
}
To me, this seems the correct way to subclass a TreeSet. But, the compiler throws the following error:
(1) No implicit Ordering defined for LengthContentsPair.
(2) not enough arguments for constructor TreeSet: (implicit ordering: Ordering[LengthContentsPair])scala.collection.immutable.TreeSet[LengthContentsPair]. Unspecified value parameter ordering.
Have I understood the scoping rules wrongly? It is something quite easy I feel, but I cannot put my hand on it.
You have defined FixedSizedSortedSet wrong. Your implementation has generic type parameter named LengthContentsPair which has nothing to do with your class with that name. In other words, you have shadowed LengthContentsPair class with generic type.
If you need a specialized set that only holds elements of LengthContentsPair, then you probably meant:
class FixedSizedSortedSet extends TreeSet[LengthContentsPair]
{ ..
}
This should work if an instance of Ordering[LengthContentsPair] is visible. But this shouldn't be a problem, since the ordering is defined in companion object of LengthContentsPair and is visible as implicit parameter by default.
But if you rather need a generic extension of TreeSet which can hold elements of any type, then you probably meant this:
class FixedSizedSortedSet[T](implicit ordering: Ordering[T]) extends TreeSet[T]
{ ..
}
Implicit parameter is needed because TreeSet requires an implicit Ordering[T], so we need to forward that requirement to FixedSizedSortedSet
BTW. I'd suggest you to consider replacing your LengthContentsPair class with a case class.

Getting implicit scala Numeric from Azavea Numeric

I am using the Azavea Numeric Scala library for generic maths operations. However, I cannot use these with the Scala Collections API, as they require a scala Numeric and it appears as though the two Numerics are mutually exclusive. Is there any way I can avoid re-implementing all mathematical operations on Scala Collections for Azavea Numeric, apart from requiring all types to have context bounds for both Numerics?
import Predef.{any2stringadd => _, _}
class Numeric {
def addOne[T: com.azavea.math.Numeric](x: T) {
import com.azavea.math.EasyImplicits._
val y = x + 1 // Compiles
val seq = Seq(x)
val z = seq.sum // Could not find implicit value for parameter num: Numeric[T]
}
}
Where Azavea Numeric is defined as
trait Numeric[#scala.specialized A] extends java.lang.Object with
com.azavea.math.ConvertableFrom[A] with com.azavea.math.ConvertableTo[A] with scala.ScalaObject {
def abs(a:A):A
...remaining methods redacted...
}
object Numeric {
implicit object IntIsNumeric extends IntIsNumeric
implicit object LongIsNumeric extends LongIsNumeric
implicit object FloatIsNumeric extends FloatIsNumeric
implicit object DoubleIsNumeric extends DoubleIsNumeric
implicit object BigIntIsNumeric extends BigIntIsNumeric
implicit object BigDecimalIsNumeric extends BigDecimalIsNumeric
def numeric[#specialized(Int, Long, Float, Double) A:Numeric]:Numeric[A] = implicitly[Numeric[A]]
}
You can use Régis Jean-Gilles solution, which is a good one, and wrap Azavea's Numeric. You can also try recreating the methods yourself, but using Azavea's Numeric. Aside from NumericRange, most should be pretty straightforward to implement.
You may be interested in Spire though, which succeeds Azavea's Numeric library. It has all the same features, but some new ones as well (more operations, new number types, sorting & selection, etc.). If you are using 2.10 (most of our work is being directed at 2.10), then using Spire's Numeric eliminates virtually all overhead of a generic approach and often runs as fast as a direct (non-generic) implementation.
That said, I think your question is a good suggestion; we should really add a toScalaNumeric method on Numeric. Which Scala collection methods were you planning on using? Spire adds several new methods to Arrays, such as qsum, qproduct, qnorm(p), qsort, qselect(k), etc.
The most general solution would be to write a class that wraps com.azavea.math.Numeric and implements scala.math.Numeric in terms of it:
class AzaveaNumericWrapper[T]( implicit val n: com.azavea.math.Numeric[T] ) extends scala.math.Numeric {
def compare (x: T, y: T): Int = n.compare(x, y)
def minus (x: T, y: T): T = n.minus(x, y)
// and so on
}
Then implement an implicit conversion:
// NOTE: in scala 2.10, we could directly declare AzaveaNumericWrapper as an implicit class
implicit def toAzaveaNumericWrapper[T]( implicit n: com.azavea.math.Numeric[T] ) = new AzaveaNumericWrapper( n )
The fact that n is itself an implicit is key here: it allows for implicit values of type com.azavea.math.Numeric to be automatically used where na implicit value of
type scala.math.Numeric is expected.
Note that to be complete, you'll probably want to do the reverse too (write a class ScalaNumericWrapper that implements com.azavea.math.Numeric in terms of scala.math.Numeric).
Now, there is a disadvantage to the above solution: you get a conversion (and thus an instanciation) on each call (to a method that has a context bound of type scala.math.Numeric, and where you only an instance of com.azavea.math.Numeric is in scope).
So you will actually want to define an implicit singleton instance of AzaveaNumericWrapper for each of your numeric type. Assuming that you have types MyType and MyOtherType for which you defined instances of com.azavea.math.Numeric:
implicit object MyTypeIsNumeric extends AzaveaNumericWrapper[MyType]
implicit object MyOtherTypeIsNumeric extends AzaveaNumericWrapper[MyOtherType]
//...
Also, keep in mind that the apparent main purpose of azavea's Numeric class is to greatly enhance execution speed (mostly due to type parameter specialization).
Using the wrapper as above, you lose the specialization and hence the speed that comes out of it. Specialization has to be used all the way down,
and as soon as you call a generic method that is not specialized, you enter in the world of unspecialized generics (even if that method then calls back a specialized method).
So in cases where speed matters, try to use azavea's Numeric directly instead of scala's Numeric (just because AzaveaNumericWrapper uses it internally
does not mean that you will get any speed increase, as specialization won't happen here).
You may have noticed that I avoided in my examples to define instances of AzaveaNumericWrapper for types Int, Long and so on.
This is because there are already (in the standard library) implicit values of scala.math.Numeric for these types.
You might be tempted to just hide them (via something like import scala.math.Numeric.{ShortIsIntegral => _}), so as to be sure that your own (azavea backed) version is used,
but there is no point. The only reason I can think of would be to make it run faster, but as explained above, it wont.

Scala: checking if an object is Numeric

Is it possible for a pattern match to detect if something is a Numeric? I want to do the following:
class DoubleWrapper(value: Double) {
override def equals(o: Any): Boolean = o match {
case o: Numeric => value == o.toDouble
case _ => false
}
override def hashCode(): Int = value ##
}
But of course this doesn't really work because Numeric isn't the supertype of things like Int and Double, it's a typeclass. I also can't do something like def equals[N: Numeric](o: N) because o has to be Any to fit the contract for equals.
So how do I do it without listing out every known Numeric class (including, I guess, user-defined classes I may not even know about)?
The original problem is not solvable, and here is my reasoning why:
To find out whether a type is an instance of a typeclass (such as Numeric), we need implicit resolution. Implicit resolution is done at compile time, but we would need it to be done at runtime. That is currently not possible, because as far as I can tell, the Scala compiler does not leave all necessary information in the compiled class file. To see that, one can write a test class with a method that contains a local variable, that has the implicit modifier. The compilation output will not change when the modifier is removed.
Are you using DoubleWrapper to add methods to Double? Then it should be a transparent type, i.e. you shouldn't be keeping instances, but rather define the pimped methods to return Double instead. That way you can keep using == as defined for primitives, which already does what you want (6.0 == 6 yields true).
Ok, so if not, how about
override def equals(o: Any): Boolean = o == value
If you construct equals methods of other wrappers accordingly, you should end up comparing the primitive values again.
Another question is whether you should have such an equals method for a stateful wrapper. I don't think mutable objects should be equal according to one of the values they hold—you will most likely run into trouble with that.

Why is a Set a function?

In Scala a Set is a function:
trait Set[A] extends (A => Boolean)
This make it impossible to have a covariant immutable Set because type A occurs in contravariant position. In contrast Seq is not defined as a function. There is already some content about the question why Sets and Seqs are designed this way:
Why is Scala's immutable Set not covariant in its type?
Scala: Why does Seq.contains take an Any argument, instead of an argument of the sequence type?
Why does Seq.contains accept type Any rather than the type parameter A?
One answer says that the reason for this is the mathematical background. But this answer wasn't explained a little more. So, what are the concrete advantages to define a Set as a function or what would be the disadvantages if it is implemented differently?
The set of type Set[A] has to have a method that tests if an element of type A is in the set. This method (apply) has to have a parameter of type A representing that element, and that parameter is in the contravariant position. This means that sets cannot be covariant in their type parameter A. So - it's not the extending of the function interface that makes it impossible to have covariant immutable sets, it's the existence of the contravariant apply method.
And for reasons of convenience, it makes sense to extend the Function1 interface to be able to pass sets around and treat them as functions.
By contrast, sequence abstraction doesn't have a method that tests if an element is in the sequence, it only has the indexing method - apply takes an integer index, and returns the element at that index. Sequences are also defined as functions, but functions of type Int => A (which are covariant in A), not A => Boolean, as sets.
If you want to know more about how type safety would be broken if sets were defined as covariant in their type parameter A, see this example in which the set implementation does some writing to private members for reasons of caching the lookups (below #uV is the annotation which disables variance checking and expensiveLookup is meant to simulate a call to a computationally expensive check if an element is in the set):
import annotation.unchecked.{uncheckedVariance => uV}
trait Set[+A] {
def apply(elem: A #uV): Boolean
}
class CachingSet[+A >: Null] extends Set[A] {
private var lastLookup: (A #uV, Boolean) = (null, false)
private def expensiveLookup(elem: A #uV) = (elem, true)
def apply(elem: A #uV): Boolean = {
if (elem != lastLookup._1) lastLookup = expensiveLookup(elem)
lastLookup._2
}
def lastQueriedElement: A = lastLookup._1
}
object Main extends App {
val css = new CachingSet[String]
val csa: CachingSet[AnyRef] = css
csa.apply(new AnyRef)
val s: String = css.lastQueriedElement // you'll get a ClassCastException here
}
In contrast Seq is not defined as a function.
Not true.
Seq[T] extends (Int) => T