Calling Java API from Scala with null argument - scala

I have some Scala code that needs to call a Java API
The Java API takes arguments that may be null. My Scala, of course, uses Option.
For example, let's say I have a Java object constructor Foo(Integer) where the Integer may be null. I want to call it given a Scala bar: Option[Int].
I tried this
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
val foo = Foo( bar.getOrElse(null) )
But got this compile error
Error:(335, 44) type mismatch;
found : Any
required: Integer
bar.getOrElse(null),
What is the correct idiom for doing this?

You don't need a Java method to reproduce this problem:
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> class Foo(a: java.lang.Integer)
defined class Foo
scala> val bar: Option[Int] = Some(5)
bar: Option[Int] = Some(5)
scala> new Foo(bar.getOrElse(null))
<console>:16: error: type mismatch;
found : Any
required: Integer
new Foo(bar.getOrElse(null))
^
The problem is that Int can't be null, so the type of bar.getOrElse(null) is Any.
scala> bar.getOrElse(null)
res0: Any = 5
scala> bar.orNull
<console>:15: error: Cannot prove that Null <:< Int.
bar.orNull
^
So you've got to convert the Option's type parameter to something that can be null before you unwrap it in a nullable way.
Quickest way I can think of immediately:
scala> new Foo(bar.map(x => x: java.lang.Integer).orNull)
res18: Foo = Foo#cdc45e
Edit: Here, I thought of a more general way to do it!
implicit class RichOption[A](o: Option[A]) {
def toRef[B >: Null](implicit f: A => B): B = o.map(f).orNull
}
Now you can write new Foo(bar.toRef) :)

No sooner do I post the question, than I spot the answer in the related list (sorry)
Here's a solution
val foo = Foo(bar.getOrElse(null).asInstanceOf[java.lang.Integer])
Kind of clunky. Anyone have anything better?

More chatter:
scala> import runtime.BoxesRunTime.boxToInteger
import runtime.BoxesRunTime.boxToInteger
scala> val x = Some(42)
x: Some[Int] = Some(42)
scala> val y: Option[Int] = None
y: Option[Int] = None
scala> x.fold(null: Integer)(boxToInteger)
res0: Integer = 42
scala> y.fold(null: Integer)(boxToInteger)
res1: Integer = null
Of course it's better to
scala> x.fold(null: Integer)(i => i: Integer)
res2: Integer = 42
and even better
scala> x.fold[Integer](null)(identity)
res3: Integer = 42
scala> y.fold[Integer](null)(identity)
res4: Integer = null

Related

Why is the simpleName for "Float" actually "float"?

The simpleName of String is literally "String":
scala> "abc".getClass.getSimpleName
res0: String = String
That makes sense, the simpleName of the type is the same name that I use to make one up in the first place, but consider Float:
scala> 32.2f
res4: Float = 32.2
scala> 23.2f.getClass.getSimpleName
res3: String = float
I was expecting 'Float' but I got '[f]loat' - why is the SimpleName behavior inconsistent with the representation of the object in the REPL?
Bonus points - is there a way that I can recover the exact name of the type I originally used, without any cumbersome mappings? What method is the REPL calling on the object to get it's correct name (with the capitol F).
The Scala type:
scala> import reflect.runtime._, universe._
import reflect.runtime._
import universe._
scala> def f[A](a: A)(implicit t: TypeTag[A]) = t
f: [A](a: A)(implicit t: reflect.runtime.universe.TypeTag[A])reflect.runtime.universe.TypeTag[A]
scala> f(2.0) // typeTag[Double]
res1: reflect.runtime.universe.TypeTag[Double] = TypeTag[Double]
scala> res1.tpe
res2: reflect.runtime.universe.Type = Double
scala> res2.typeSymbol.name
res3: reflect.runtime.universe.Symbol#NameType = Double
The boxed distinction is strictly an artifact of the underlying platform.
scala> java.lang.Float.TYPE
res4: Class[Float] = float
scala> classOf[java.lang.Float]
res5: Class[Float] = class java.lang.Float
What method is the REPL calling on the object to get it's correct name (with the capitol F).
It isn't calling any method on the object; if it did, it couldn't show two different types for the same object:
scala> val x = ""
res1: String = ""
scala> val y: Object = x
res2: Object = x
It's using compiler's information about types which can be accessed using TypeTags as som-snytt's answer shows.

Why does function expecting type alias input does not typechecks if I pass undelying type?

In the following code, why is the compiler not able to infer that x1 is immutable when passed to function imSeq.
def imSeq(e: scala.collection.immutable.Seq[Int]) = e.foreach(println)
def mSeq(e: Seq[Int]) = e.foreach(println)
scala> val x1 = Seq(1, 2, 3)
x1: Seq[Int] = List(1, 2, 3)
scala> x1.isInstanceOf[scala.collection.immutable.List[Int]]
res11: Boolean = true
scala> x1.isInstanceOf[scala.collection.immutable.Seq[Int]]
res12: Boolean = true
scala> x1.isInstanceOf[scala.collection.mutable.Seq[Int]]
res13: Boolean = false
scala> imSeq(x1)
<console>:10: error: type mismatch;
found : Seq[Int]
required: scala.collection.immutable.Seq[Int]
imSeq(x1)
^
That's because you explicitly require an instance of immutable.Seq in your function, but the pre-imported Seq trait is not just an alias for immutable.Seq, it's actually a base trait of immutable.Seq. In other words, immutable.Seq extends Seq.
Generalize the accepted type:
def imSeq(e: Seq[Int]) = e.foreach(println)

How to find the type of a Scala expression

Can I find out the type of an expression in Scala. This would be particuarly useful when debugging complex partial functions, implicit conversions, etc...
For example:
println( typeOf( x+y ) )
If you wish to print as you have specified then:
scala> def manOf[T: Manifest](t: T): Manifest[T] = manifest[T]
manOf: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T]
scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)
scala> println(manOf(x))
scala.collection.immutable.List[Int]
If you are in repl mode then
scala> :type List(1,2,3)
List[Int]
In the scala console, you can use :type:
:type x+y
At runtime (including in the console) you can do:
scala> import reflect.ClassTag
import reflect.ClassTag
scala> def exprType[T:ClassTag]( x: T ) = implicitly[ClassTag[T]]
exprType: [T](x: T)(implicit evidence$1: scala.reflect.ClassTag[T])scala.reflect.ClassTag[T]
scala> exprType( x+y)
res1: scala.reflect.ClassTag[String] = java.lang.String
exprType will return the ClassTag the parameter. Because ClassTag are not resilient to erasure, you might want to use a TypeTag instead (but this requires to have "scala-reflect.jar" in the classpath):
import reflect.runtime.universe._
def exprType[T:TypeTag]( x: T ) = implicitly[TypeTag[T]]

Is it possible to get the type of a type field after creating an object?

Is it possible to get the type of a type field after creating an object ?
I would like to do something like this:
scala> class A { type T = String }
defined class A
scala> val a = new A
a: A = A#591171
scala> a.T
<console>:13: error: value T is not a member of A
a.T
^
The last
What do you want to do with the type? You can use a type projection in various ways with the class's type (without an instance):
scala> class A { type T = String }
defined class A
scala> val x: A#T = "test"
x: java.lang.String = test
scala> def f(b: A#T) = b
f: (a: java.lang.String)java.lang.String
Or if you enable -Ydependent-method-types, you can get the type member from the instance:
scala> val a = new A
a: A = A#6a3de2df
scala> val x: a.T = "test"
x: a.T = test
scala> def f(b: a.T) = b
f: (b: a.T)a.T
Scala's reflection API prior to 2.10 doesn't really model types in any clean way, so if you want to "get the type" in some other sense, you're probably out of luck.
One way is with reflection (since 2.10M4):
// with static types
scala> class A { type T = String }
defined class A
scala> import reflect.runtime.{universe => u}
import reflect.runtime.{universe=>u}
scala> val t = u.typeOf[A]
t: reflect.runtime.universe.Type = A
scala> val types = t.declarations.filter(_.isType)
types: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(type T)
scala> types.toList.head.typeSignature
res9: reflect.runtime.universe.Type = String
// with instances
scala> val a = new A
a: A = A#68d7c870
scala> import reflect.runtime.{currentMirror => m}
import reflect.runtime.{currentMirror=>m}
scala> m.reflect(a).symbol.asType // same type as t
res20: reflect.runtime.universe.Type = A

Methods versus Function and implicits in Scala

Let's declare a def and an equivalent function as a val:
scala> def optional(x:Int):Option[String] = None
optional: (x: Int)Option[String]
scala> val optional2:(Int)=>Option[String] = (i:Int) => None
optional2: Int => Option[String] = <function1>
Now why doesn't this work?
scala> List(1).flatMap(optional2)
<console>:9: error: type mismatch;
found : Int => Option[String]
required: Int => scala.collection.GenTraversableOnce[?]
List(1).flatMap(optional2)
^
While both of these do?
scala> List(1).flatMap(optional)
res4: List[String] = List()
scala> List(1).flatMap(optional2(_))
res5: List[String] = List()
Since Option is not a subtype of GenTraversableOnce, I think this must have something to do with implicits, but I can't figure out what exactly it is. I am using Scala 2.9.1.
The implicit conversion Option.option2Iterable is what makes List(1).flatMap(optional) and List(1).flatMap(optional2(_)) work.
Your issue can be boiled down to the implicit conversion not being picked up:
scala> val optional2:(Int)=>Option[String] = (i:Int) => None
optional2: Int => Option[String] = <function1>
scala> (optional2(_)): Function[Int, Iterable[String]]
res0: Int => Iterable[String] = <function1>
scala> (optional2): Function[Int, Iterable[String]]
<console>:9: error: type mismatch;
found : Int => Option[String]
required: Int => Iterable[String]
When you use the underscore, the compiler attempts to type the function and provide the necessary implicit conversion. When you just provide optional2, there is no implicit conversion that applies.