Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - Option.getOrElse() "type erasure"?

I am trying to use the Option.getOrElse() method but it returns etiher Any or ScalaObject instead of an instance of the correct class that the Option was parametrized with. I can't find any mention about this problem and it does not seem like it should be there. What am I doing wrong?

class MyClass {

  def isOk = true

}

val myVal = Some(new MyClass) // :Option[MyClass]

val check = myVal.getOrElse(false).isOk

Can't call the isOk method because it tries calling it upon Any.

like image 279
noncom Avatar asked Nov 27 '22 00:11

noncom


2 Answers

You are trying to call method isOk on base class of MyClass and Boolean (Any).

Try this:

scala> class MyClass(b: Boolean) { def isOk = b }
defined class MyClass

scala> val myVal = Some(new MyClass(true))
myVal: Some[MyClass] = Some(MyClass@35d56bbe)

scala> myVal.map{_.isOk}.getOrElse(false)
res0: Boolean = true

scala> myVal.getOrElse(new MyClass(false)).isOk
res1: Boolean = true
like image 116
senia Avatar answered Nov 29 '22 13:11

senia


Works as designed. This expression:

myVal.getOrElse(false)

returns either unwrapped MyClass instance or (if Option is actually None) - false. The only common type of MyClass and Boolean is... Any. And this is what you are seeing.

In order for this to work you must return something compatible with MyClass from getOrElse():

myVal.getOrElse(new MyClass).isOk

Or maybe you want to implement null-object pattern:

object MyClass {
  val Empty = new MyClass
}

myVal.getOrElse(MyClass.Empty).isOk
like image 20
Tomasz Nurkiewicz Avatar answered Nov 29 '22 14:11

Tomasz Nurkiewicz