odd isInstanceOf behavior in Scala - scala

using the ScalaTest/FlatSpec library I am testing the types of returned values from a random number generator using functional state:
it should "return (\"{someRandomNumber}\", rng2) on nonNegativeInt.map(_.toString)" in {
val s = RNG.map(RNG.nonNegativeInt)(_.toString)(rng)
assert(s.isInstanceOf[(Int, RNG)]) // WRONG but PASS!!
assert(s._2 !== rng)
}
now if you notice the incorrect isInstanceOf[(Int, RNG)] you would think that this would produce a fail, however it succeeds.
the following code demonstrates that this passes as long as the tuple has the correct arity:
it should "not work" in {
assert(("123", rng).isInstanceOf[(Int, RNG)]) // PASS
assert(("123", rng).isInstanceOf[(String, Nothing)]) // PASS
assert(("123", rng).isInstanceOf[(Exception, Array[_])]) // PASS
}
but if the tuple has one type parameter:
it should "also not work" in {
assert(("123").isInstanceOf[Int]) // FAIL
}
What is going on here? how should I test the inner parameterized types?

Don't ever forget that scala is backed by plain old java, inheriting all its nuances. Java performs runtime type erasure for generic classes. So your (Int, Rng) in runtime is Tuple2(Object, Object), so is your s.
You can find some useful information how to work around that issue in scala here.

Related

Add ArrayBuffer Element via def in Scala

I am curious as to how to add an ArrayBuffer element via a def. E.g.
def addToArray[T](data: ArrayBuffer[T]): ArrayBuffer[T] = {
return(data += T("XYZ"))
}
I tried this but no go. I assume we cannot do this generically, but I would like to know how to do this. If I do this, return(new ArrayBuffer[T]()), it works. Not the most difficult but somehow escaping me.
Just give the def your generic buffer and the element you want to add then return it:
def addToArrayBuffer[T](data: ArrayBuffer[T], elem: T): ArrayBuffer[T] = {
data += elem
data
}
println(addToArrayBuffer(ArrayBuffer(1, 2, 30), 4)) // ArrayBuffer(1, 2, 30, 4)
If you are not passing the element you want to add as a parameter to the def, then you can't add it inside the def. The idea is that you cannot create an instance of a type parameter, because instantiation requires a constructor which is unavailable if the type is unknown. This restriction is mentioned in the Java generics spec here:
Cannot Create Instances of Type Parameters: You cannot create an
instance of a type parameter. For example, the following code causes a
compile-time error:
public static <E> void append(List<E> list) {
E elem = new E(); // compile-time error
list.add(elem);
}
Wikipedia also explains this very nicely:
Java generics differ from C++ templates. Java generics generate only
one compiled version of a generic class or function regardless of the
number of parameterizing types used. Furthermore, the Java run-time
environment does not need to know which parameterized type is used
because the type information is validated at compile-time and is not
included in the compiled code. Consequently, instantiating a Java
class of a parameterized type is impossible because instantiation
requires a call to a constructor, which is unavailable if the type is
unknown.
Note that there might be a workaround to this using reflection, which is further detailed in the spec.

Difference between type inference of method and class type parameters in pattern matching

Why does pattern matching work differently when type parameter comes from an enclosing method as opposed to an enclosing class? For example,
trait Base[T]
case class Derived(v: Int) extends Base[Int]
class Test[A] {
def method(arg: Base[A]) = {
arg match {
case Derived(_) => 42
}
}
}
gives error
constructor cannot be instantiated to expected type;
found : A$A87.this.Derived
required: A$A87.this.Base[A]
case Derived(_) => 42
^
whilst it successfully compiles when A is method type parameter
class Test {
def method[A](arg: Base[A]) = {
arg match {
case Derived(_) => 42
}
}
}
The question is based on Daniel's analysis, which I used to attempt to provide answer to similar question.
I don't have the 100% complete answer, but I have a pointer that might be sufficient for you.
Scala compiler deals with GADTs (Generalized Algebraic Data Types) in a very particular way. Some cases are solved with special handling, some cases are unsolved. Dotty is trying to fill most of the holes, and it has already solved a lot of related issues, however there are still quite a few open ones as well.
Typical example of special GADT handling in Scala 2 compiler is very related to your use case. If we take a look at:
def method[A](arg: Base[A]) = {
arg match {
case Derived(_) => 42
}
}
and we explicitly declare the return type to be A:
def method[A](arg: Base[A]): A
it will compile just fine. Your IDE might complain, but the compiler will let it through. Method says it returns an A, but the pattern matching case evaluates into an Int, which theoretically shouldn't compile. However, special handling of GADTs in the compiler says it's fine, because in that particular pattern matching branch A has been "fixed" to be an Int (because we matched on Derived which is a Base[Int]).
Generic type parameter for the GADT (in our case A) has to be declared somewhere. And here's the interesting part - special compiler handling only works when it's declared as the type parameter of the enclosing method. If it's coming from a type member or a type parameter of the enclosing trait/class, it doesn't compile, as you witnessed yourself.
This is why I said it's not a 100% complete answer - I cannot point to a concrete place (such as official specification) which documents this properly. Sources on handling of GADTs in Scala come down to a couple of blogposts, which are great by the way, but if you want more than that you will have to dig into the compiler code yourself. I tried doing exactly that, and I think it comes down to this method, but if you really want to go deeper, you might want to ping someone more experienced with the Scala compiler codebase.

Scala, why do I not need to import deduced types

I feel like I should preface this with the fact that I'm building my projects with sbt.
My problem is that, if at compile time a method returns something of an unimported type, in the file where I call the method, as long as I use type inference, everything compiles. Once I try to assign the unimported type to the var/val which I created with the return value of my function, I get a compiler error.
Lets say I have two classes in two package. Class App in package main and class Imported in package libraries. Lets further more say that we have a class ImportedFactory in the package main and that this class has a method for creating objects of the type Imported.
This code compiles just fine:
class App() {
// method return object of type Imported
val imp = ImportedFactory.createImportedObject()
}
This doesn't:
class App() {
// method return object of type Imported
val imp : Imported = ImportedFactory.createImportedObject()
}
This yet again does:
import libraries.Imported
class App() {
// method return object of type Imported
val imp : Imported = ImportedFactory.createImportedObject()
}
This seems like rather strange behavior. Is this normal for languages with type inference at compile time and I've yet to notice it until now in go/C++ due to my ignorance ?
Does one of the two valid approaches (import&explicit type vs infered) have advantages/drawback over the other ? (expect for, of course, one being more explicit and verbose and the other one being shorter)
Is this black magic or does the Scala compiler accomplish these deductions in a rather straight forward way ?
The only thing importing does is making a not fully qualified name available in the current scope. You could just as well write this:
class App() {
val imp: libraries.Imported = ImportedFactory.createImportedObject()
}
The reason you import libraries.Imported is for making the shorter name Imported available for you to write. If you let the compiler infer the type, you don't mention the type in your code, so you don't have to import its shorter name.
And by the way: this has nothing to do with dynamic casting in C++. The only mechanism at work in your code is type inference.
note: You'll get better search results with the term type inference
With val imp = ImportedFactory.createImportedObject() you are letting the compiler figure out what type imp should be based on type inference. Whatever type createImportObject returns, that's what type imp is.
With val imp : Imported = ImportedFactory.createImportedObject() you are explicitly stating that imp is an Imported. But the compiler doesn't know what you mean by that unless you... import... it.
Both approaches have merit:
inferred types
Inferred types are great for when you're throwing together code where the type should be obvious:
val i = 1 // obviously `i` is an int
val j = i + 10 // obviously still an int
It's also great for local vars/vals where the type would be too much of a pain to write
val myFoo: FancyAbstractThing[TypeParam, AnotherTypeParam[OhNoMoreTypeParams]] = ...
// vs
val myFoo = FancyThingFactory.makeANewOne()
The downside is that if you have allowed a public def/val to have an inferred type, it can be more difficult to determine how to use that method. For this reason, omitting type annotations is typically only used for simple constants, and in local vals/vars that "client code" doesn't have to look at.
explicit types
When you do want to write library-ish code (i.e. public vals/defs), the convention is to explicitly-type them.
Probably the simplest reason for this is because this:
def myLibraryMethod = {
// super complicated implementation
}
is harder to understand than
def myLibraryMethod: String = {
// super complicated implementation
}
Another benefit to explicitly-typing your code is when you want to expose a less-specific type than what the value actually is:
val invalidNumbers: Set[Int] = TreeSet(4, 8, 15, 16, 23, 42)
In this example, you don't want client code to need to care that your invalidNumbers is actually a TreeSet. That's an implementation detail. In this case you're hiding some information that, while true, would be distracting.

Scala: understanding how to make my method return the proper return type of Array

I have written the following Scala code:
class MyTestApi {
private def toCPArray(inputStr: String): Array[Int] = {
val len = inputStr.length
//invoke ofDim of Scala.Array
val cpArray = Array.ofDim[Int](inputStr.codePointCount(0, len))
var i = 0
var j = 0
while (i < len) {
cpArray(j += 1) = inputStr.codePointAt(i)
i = inputStr.offsetByCodePoints(i, 1)
}
cpArray
}
}
This is what I want to accomplish:
I would create an instance of class MyTestApi and then invoke the method toCPArray and pass to it a parameter of type String. I would then like this method to return me an `Array[Int].
However as it stands now, the Scala IDE is complaining about this line:
**cpArray(j += 1) = inputStr.codePointAt(i)**
type mismatch; Found: Unit required: Int
Two things I would like to accomplish are:
How would I fix this method? (or is it a function)
My hope is, after I understand what it takes to fix this method (or function) I will be able to return the appropriate type. Also, I should be in better position to understand the difference between a method and a function.
So far my research on stackoverflow and Martin Odersky's book seems to suggests to me that what I wrote is a method because it is invokded on an instance of the underlying class. Is my understanding right on that?
After it is fixed, how can i rewrite it in a more Scalaesque way, by getting rid of the var. The code looks more C or java like right now and is a little long in my opinion, after all that I have studied about Scala so far.
Thanks for any help in refactoring the above code to accomplish my learning objectives.
You are calling cpArray.update with an assignment statement which evaluates to Unit when it expects an Integer. You need to call it with an Integer:
j += 1
cpArray(j) = inputStr.codePointAt(i)
Many questions in one. I try to answer them all.
First of all as Jörg pointed out, moving the assignment makes the code work. Contrary to Java and C, Scala's assignment doesn't return the assigned value but Unit.
Now for making it idiomatic. Scala's String can be seem as IndexedSeq[Char], meaning you can generally treat them as IndexedSeqs. So you doing do something like:
inputStr.map{ x => x.toInt }.toArray
This will return an Array[Int]. Notice it will only work for 16-bits char representations. Hopefully it will help in giving an idea of idiomatic Scala, even not being a perfect solution.
For the difference between methods and functions, it's simple: methods are generally defs in a class. Functions one the other hands are Objects in the JVM sense. For example, the above map could be defined like:
def map(f: Function1[Char, Int]):IndexedSeq[Int]
// or
def map(f: Char => Int):IndexedSeq[Int]
Both are the same, => desugars to one of the scala.FunctionN (N from 0 to 22 inclusive).
And x => x.toInt is desugared in a similar way into a instance of scala.Function1. See it's Scaladoc.
So, functions are objects of type scala.FunctionN.
Note: to keep things simple I omitted a few details like type parameters, vals (which often compiles to JVM methods) and probably a few more details.

Scala: Why use implicit on function argument?

I have a following function:
def getIntValue(x: Int)(implicit y: Int ) : Int = {x + y}
I see above declaration everywhere. I understand what above function is doing. It is a currying function which takes two arguments. If you omit the second argument, it will invoke implicit definition which returns int instead. So I think it is something very similar to defining a default value for the argument.
implicit val temp = 3
scala> getIntValue(3)
res8: Int = 6
I was wondering what are the benefits of above declaration?
Here's my "pragmatic" answer: you typically use currying as more of a "convention" than anything else meaningful. It comes in really handy when your last parameter happens to be a "call by name" parameter (for example: : => Boolean):
def transaction(conn: Connection)(codeToExecuteInTransaction : => Boolean) = {
conn.startTransaction // start transaction
val booleanResult = codeToExecuteInTransaction //invoke the code block they passed in
//deal with errors and rollback if necessary, or commit
//return connection to connection pool
}
What this is saying is "I have a function called transaction, its first parameter is a Connection and its second parameter will be a code-block".
This allows us to use this method like so (using the "I can use curly brace instead of parenthesis rule"):
transaction(myConn) {
//code to execute in a transaction
//the code block's last executable statement must be a Boolean as per the second
//parameter of the transaction method
}
If you didn't curry that transaction method, it would look pretty unnatural doing this:
transaction(myConn, {
//code block
})
How about implicit? Yes it can seem like a very ambiguous construct, but you get used to it after a while, and the nice thing about implicit functions is they have scoping rules. So this means for production, you might define an implicit function for getting that database connection from the PROD database, but in your integration test you'll define an implicit function that will superscede the PROD version, and it will be used to get a connection from a DEV database instead for use in your test.
As an example, how about we add an implicit parameter to the transaction method?
def transaction(implicit conn: Connection)(codeToExecuteInTransaction : => Boolean) = {
}
Now, assuming I have an implicit function somewhere in my code base that returns a Connection, like so:
def implicit getConnectionFromPool() : Connection = { ...}
I can execute the transaction method like so:
transaction {
//code to execute in transaction
}
and Scala will translate that to:
transaction(getConnectionFromPool) {
//code to execute in transaction
}
In summary, Implicits are a pretty nice way to not have to make the developer provide a value for a required parameter when that parameter is 99% of the time going to be the same everywhere you use the function. In that 1% of the time you need a different Connection, you can provide your own connection by passing in a value instead of letting Scala figure out which implicit function provides the value.
In your specific example there are no practical benefits. In fact using implicits for this task will only obfuscate your code.
The standard use case of implicits is the Type Class Pattern. I'd say that it is the only use case that is practically useful. In all other cases it's better to have things explicit.
Here is an example of a typeclass:
// A typeclass
trait Show[a] {
def show(a: a): String
}
// Some data type
case class Artist(name: String)
// An instance of the `Show` typeclass for that data type
implicit val artistShowInstance =
new Show[Artist] {
def show(a: Artist) = a.name
}
// A function that works for any type `a`, which has an instance of a class `Show`
def showAListOfShowables[a](list: List[a])(implicit showInstance: Show[a]): String =
list.view.map(showInstance.show).mkString(", ")
// The following code outputs `Beatles, Michael Jackson, Rolling Stones`
val list = List(Artist("Beatles"), Artist("Michael Jackson"), Artist("Rolling Stones"))
println(showAListOfShowables(list))
This pattern originates from a functional programming language named Haskell and turned out to be more practical than the standard OO practices for writing a modular and decoupled software. The main benefit of it is it allows you to extend the already existing types with new functionality without changing them.
There's plenty of details unmentioned, like syntactic sugar, def instances and etc. It is a huge subject and fortunately it has a great coverage throughout the web. Just google for "scala type class".
There are many benefits, outside of your example.
I'll give just one; at the same time, this is also a trick that you can use on certain occasions.
Imagine you create a trait that is a generic container for other values, like a list, a set, a tree or something like that.
trait MyContainer[A] {
def containedValue:A
}
Now, at some point, you find it useful to iterate over all elements of the contained value.
Of course, this only makes sense if the contained value is of an iterable type.
But because you want your class to be useful for all types, you don't want to restrict A to be of a Seq type, or Traversable, or anything like that.
Basically, you want a method that says: "I can only be called if A is of a Seq type."
And if someone calls it on, say, MyContainer[Int], that should result in a compile error.
That's possible.
What you need is some evidence that A is of a sequence type.
And you can do that with Scala and implicit arguments:
trait MyContainer[A] {
def containedValue:A
def aggregate[B](f:B=>B)(implicit ev:A=>Seq[B]):B =
ev(containedValue) reduce f
}
So, if you call this method on a MyContainer[Seq[Int]], the compiler will look for an implicit Seq[Int]=>Seq[B].
That's really simple to resolve for the compiler.
Because there is a global implicit function that's called identity, and it is always in scope.
Its type signature is something like: A=>A
It simply returns whatever argument is passed to it.
I don't know how this pattern is called. (Can anyone help out?)
But I think it's a neat trick that comes in handy sometimes.
You can see a good example of that in the Scala library if you look at the method signature of Seq.sum.
In the case of sum, another implicit parameter type is used; in that case, the implicit parameter is evidence that the contained type is numeric, and therefore, a sum can be built out of all contained values.
That's not the only use of implicits, and certainly not the most prominent, but I'd say it's an honorable mention. :-)