scala.Some cannot be cast to java.lang.String - scala

In this application, I'm getting this error:
scala.Some cannot be cast to java.lang.String
When trying this:
x.email.asInstanceOf[String]
x.email is an Option[String]
Edit: I understand that I'm dealing with different types here, I was just wondering if there were a more concise way to do nothing with None then a
match { case....}
sequence. Because I am casting x.email into a String for JSON purposes, a null field will be handled by the JSON object, and I don't explicitly have to deal with it. Sorry for being unclear!!

Well, it's clear to you from the errors and types that x.email is not a String...
First, decide how you want to handle None (a valid option for something of type Option[String]). You then have a number of options, including but not limited to:
x.email match {
case None => ...
case Some(value) => println(value) // value is of type String
}
Alternately, take a look at the get and getOrElse methods on class Option.
If you want to "degrade" the option to a String with a possible null value, then use
x.email.orNull // calls getOrElse(null)
Finally, if you just don't care about the None case (and want to ignore it), then just use a simple "for comprehension" which will "skip" the body in the None case:
for (value <- x.email) {
// value is of type String
}

Casting isn't how you should be looking at conversions when it comes to Options. Have a look at the following REPL session:
C:\>scala -deprecation -unchecked
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0).
Type in expressions to have them evaluated. Type :help for more information.
scala> val email:Option[String] = Some("x#y.com")
email: Option[String] = Some(x#y.com)
scala> email.getOrElse("defaults#example.com")
res0: String = x#y.com
scala>
You might also want to look at this SO question: What is the point of the class Option[T]?
and the Options API here
Generally speaking, casting/coercion are kind-of taboo in FP world. :)

x.map(_.toString).getOrElse("")

You may want use pattern matching:
x.email match {
case Some(email) => // do something with email
case None => // did not get the email, deal with it
}

Related

Scala, how to not use None

I have a bit of code that I am checking with Scala Scapegoat. I am not sure how to refactor this code the way it wants.
def strToDouble(valueParam: Option[String]): Option[java.lang.Double] = {
valueParam.map(value => {
Try {
Double.box(value.toDouble)
}.recoverWith({
case e: NumberFormatException => {
val logger = LoggerFactory.getLogger(getClass.getName)
logger.warn("error parsing string to double", e)
return None
}
}).getOrElse(null)
})
}
Scapegoat is complaining about my use of return and the getOrElse(null). Unfortunately in this situation I can't figure out how to do what I want:
convert the string to double, returning Option[Double]
log an error if there is a parsing error
return None in the case of parsing error
any ideas?
In general in Scala, you never need to use return, and it has some surprising semantics so it's generally advised to never use return.
Instead of return, the result of a block expression (such as the body of a function) is the result of the last expression evaluated in the block.
I would write your code along these lines
valueParam.flatMap { value =>
val attempt =
Try {
Double.box(value.toDouble)
}
attempt.recoverWith {
case e: NumberFormatException =>
val logger = LoggerFactory.getLogger(getClass.getName)
logger.warn("error parsing string to double", e)
attempt
}.toOption
}
The first key difference is that since we're transforming an Option into another Option, and might sometimes turn a Some into a None (e.g. Some("hello")), flatMap is called for.
Saving the Try[Double] in a local val enables us to get around there not being a foreach equivalent on a failed Try, thus the recoverWith which results in the same Try after side-effecting.
At the end, we convert the Try into an Option with toOption.
null is generally never used in Scala, with Option preferred (and an Option which could be null is especially verboten, as it's virtually guaranteed to blow up). If you have an Option[java.lang.Double] and need a possibly null java.lang.Double in order to work with a Java API, the orNull method on an Option is probably the most idiomatic thing to use.
I'm fairly sure that scala.Double is, on the JVM, a compiler-synthesized alias for java.lang.Double, so Double.box might not be needed.
Everything that #Levi said. I just have a preference for fold() in place of recooverWith().
import scala.util.Try
def strToDouble(valueParam: Option[String]): Option[Double] =
valueParam.flatMap { value =>
Try(value.toDouble).fold({
case e:NumberFormatException =>
LoggerFactory.getLogger(getClass.getName)
.warn("error parsing string to double", e)
None
}, Some(_))
}

Casting error from Option[Double] to Double in scala

I am facing a problem in casting from Option[Double] to Double. I am getting the following exception error:
scala.Some cannot be cast to java.lang.Double
val ty = ttnew.distinct().leftOuterJoin(rank).map{ case ((key),(c,d)) => (key,c._1,c._2,c._3,d.getOrElse(Double).asInstanceOf[Double]) }
Please Help!
d.getOrElse(Double).asInstanceOf[Double]
makes no sense.
Assuming d is an Option[Double] if you want to have a Double you cannot cast it, you need to get the value "out of" the Option.
getOrElse allows you to get the value if present, and provide a fallback value if absent (i.e. None).
For example:
d.getOrElse(0) // 0, or anything that makes sense as a fallback
If d has type Option[Double] then d.getOrElse(0) has type Double.
that's not how you deal with Option. Use .getOrElse or a .map
val ty=ttnew.distinct().leftOuterJoin(rank).map{ case ((key),(c,d)) => (key,c._1,c._2,c._3,d.getOrElse(Double).asInstanceOf[Double]) }
probably (in this situation) you will want to do d.getOrElse(<a-good-default-value-like-zero-maybe>)
other situations maybe you want to propagate the meaning of Option (the value may not exist), and in those cases you should use the .map:
val res: Option[String] = optionalDouble.map(doubleValue => callSomeFunctionThatConvertsDoubleToString(value))
you can even do other things using pattern matching and extractors. for instance, using .collect (it's a .map, but there may be cases not covered):
val ty=ttnew.distinct().leftOuterJoin(rank).collect{ case ((key),(c,Some(d))) => (key,c._1,c._2,c._3,d) }

Checking null value in Scala for Java data type [duplicate]

This question already has an answer here:
Best practice for null-checking in Scala
(1 answer)
Closed 6 years ago.
I have call in Scala code which give Java Double type which can be null how can I check between null and non-null value in Scala code?
val myJavaDoubleValue: Double = thirdpartyCall.collectValue()
if(myJavaDoubleValue == null) {
println("Is NULL")
} else {
println("Is NOT NULL")
}
Any suggestion on doing this in Scala way?
Use an Option:
val myJavaDoubleValue: Option[Double] = Option(thirdpartyCall.collectValue())
The above will result in None if the result is null, otherwise in Some(actualValue).
See Option.apply()
Scala supports null in the same way as Java. So your code is syntatically correct.
However, a more modern approach would be to make sure your code almost never can touch null values. In order to do that, one possible way is using Scala Option class. An Option[T] is an value that may or may not be defined. A defined option is represented by Some[T], while a non-defined option is represented by None.
Option(thirdpartyCall.collectValue()) will return a Option[Double]. There are multiple ways to check the value contained in an Option, one of the Scala-idiomatic ways to perform what you want to do is pattern matching:
Option(thirdpartyCall.collectValue()) match {
case Some(value) =>
println(s"value is defined: $value")
case None =>
println("value is not defined")
}
However, Option is much more powerful than that. It supports methods like map, flatMap and fold which allow you to be even more expressive, for example:
def optionIsDefined[A](a: A) = Option(a).fold("not defined") { value => s"defined with value: $value" }
scala> optionIsDefined(42)
res2: String = defined with value: 42
scala> optionIsDefined(null)
res3: String = not defined
This is a great newcomers' friendly guide on Option.

avoid type conversion in Scala

I have this weird requirement where data comes in as name ->value pair from a service and all the name-> value type is string only (which really they are not but that's how data is stored)
This is a simplified illustration.
case class EntityObject(type:String,value:String)
EntityObject("boolean","true")
now when getting that EntityObject if type is "boolean" then I have to make sure value is not anything else but boolean so first get type out and check value and cast value to that type. e.g in this case check value is boolean so have to cast string value to boolean to validate. If it was anything else besides boolean then it should fail.
e.g. if data came in as below, casting will fail and it should report back to the caller about this error.
EntityObject("boolean","1")
Due to this weird requirement it forces type conversion in validation code which doesn't look elegant and against type safe programming. Any elegant way to handle this in scala (may be in a more type safe manner)?
Here is where I'm going to channel an idea taken from a tweet by Miles Sabin in regards to hereogenous mappings (see this gist on github.) If you know the type of object mapping names a head of time you can use a nifty little trick which involves dependent types. Hold on, 'cause it's a wild ride:
trait AssocConv[K] { type V ; def convert: String => V }
def makeConv[V0](name: String, con: String => V0) = new AssocConv[name.type]{
V = V0
val convert = con
}
implicit val boolConv = makeConv("boolean", yourMappingFunc)
def convEntity(name: String, value: String)(implicit conv: AssocConv[name.type]): Try[conv.V] = Try{ conv.convert(value) }
I haven't tested this but it "should" work. I've also enclosed it in a Scala Try so that it catches exceptions thrown by your conversion function (in case you're doing things like _.toInt as the converter.)
You're really talking about conversion, not casting. Casting would be if the value really were an instance of Boolean at runtime, whereas what you have is a String representation of a Boolean.
If you're already working with a case class, I think a pattern matching expression would work pretty well here.
For example,
def convert(entity : EntityObject) : Any = entity match {
case EntityObject("boolean", "true") => true
case EntityObject("boolean", "false") => false
case EntityObject("string", s) => s
// TODO: add Regex-based matchers for numeric types
}
Anything that doesn't match one of the specified patterns would cause a MatchError, or you could put a catchall expression at the end to throw your own exception.
In this particular example, since the function returns Any, the calling coffee would need to do an actual type cast to get the specific type, but at least by that point all validation/conversion would have already been performed. Alternatively, you could just put the code that uses the values directly into the above function and avoid casting. I don't know what your specific needs are, so I can't offer anything more detailed.

Get Option value or throw an exception

Given an Option, what is the idiomatic way to get its value or throw an exception trying?
def foo() : String = {
val x : Option[String] = ...
x.getOrException()
}
A throw "statement" is really an expression in Scala, and it has type Nothing, which is a subtype of every other type. This means you can just use plain old getOrElse:
def myGet[A](oa: Option[A]) = oa.getOrElse(throw new RuntimeException("Can't."))
You really, really shouldn't be doing this, though.
(EDIT: this is not the best or most idiomatic way to do it. I wrote it when I was not familiar with Scala. I leave it here for an example of how not to do it. Nowadays I would do as #TravisBrown)
I think it really boils down to two things:
how sure are you that the value is there?
how do you want to react if it isn't?
If at that point in your code you expect the value to be there, and in the remote case that it isn't you want your program to fail fast, then I would only do a normal get and let Scala throw a NoSuchElementException if there was no value:
def foo() : String = {
val x : Option[String] = ...
x.get
}
If you want to handle the case differently (throw your own exception) I think a more elegant way would look like this:
def foo(): String = {
val x: Option[String] = None
x match {
case Some(value) => value
case None => throw new MyRuntimeException("blah")
}
}
And of course if you want to supply your own alternative value for the case that the Option is None you would just use getOrElse:
def foo(): String = {
val x: Option[String] = None
x.getOrElse("my alternative value")
}
I hope this will help you to understand how to represent errors (and generally effects) using types.
Error handling strategies in functional Scala
Use Option to return optional values. For example - fail to find entity in storage.
Use Option(possiblyNull) to avoid instances of Some(null).
Use Either[Error, T] to report expected failure. For example - email format is wrong, cannot parse a string to a number, etc.
Model your errors as ADTs (simply speaking kind of type hierarchies) to use it, for example, on the Left of the Either to represent more complex error scenarios.
Throw Exception only to signal unexpected and not-recoverable failures. Like missing config file.
Use Either.catchOnly or Try or Cats.IO (advanced) rather than a catch block for handling unexpected failures. Hint: You can still use ADT but extend them from throwables. More about Either vs Try.
Use Validated data-type from Cats lib to accumulate errors rather than fail-fast (Either), but prefer Either's on module-level to simplify the composition of the program (to have the same types). For example - form data validation, parsing errors accumulation.
Use mentioned types and don't optimize program preemptively - since most probably, bottle-necks would be in business logic, not in effect types.
Such an approach will simplify maintenance and updates of your code since you can reason about it without going to implementation specifics (aka local-reasoning). Also - reduce bugs - you cannot miss an error in the type. And compose the program easier (with help of map, flatMap and other combinators) - since it's simpler on type level, rather than with non-local exceptions and side-effects.
More about learning functional Scala.
But be aware that sometimes with this approach types could stack up and it could become harder to compose things. Given, for example: x: Future[Either[Error, Option[T]]] What you can do:
Use map and flatMap in combination with pattern-matching to compose different values of such types, for example:
x.faltMap { case Right(Some(v)) => anotherFuture(v); case Left(er) => ... }
If it doesn't help you can try to use MonadTransformers (don't be scared of the name, it's just wrappers around the effect types like Either and Future)
Also, an option is to simplify your errors ADT by extending them from the Throwable to unify it with Future, then it'll be Future[Option[T]]
And finally, in your case one option will be:
def foo() : Either[Error, String] = {
val x : Option[String] = ...
x match {
case Some(v) => Right(v)
case None => Left(Error(reason))
}
}
Just use the .get method.
def get[T](o:Option[T]) = o.get
It will throw a NoSuchElementException if o is an instance of None.
Basically, I would work with options like this:
def addPrint(oi:Option[Int]) = oi.map(_+1).foreach(println)
addPrint(Some(41))
addPrint(Some(1336))
addPrint(None)
to avoid your specific question.
Scala now support this operation on maps using getOrElse() method, see documentation here
As pointed out already, throwing an exception in Scala is an expression as well.
So you can do the following:
myMap.getOrElse(myKey, throw new MyCustomException("Custom Message HERE")