Odd Scala ClassCastException - scala

The following code compiles, but throws an exception on the last line. Why is this? How can I avoid it? (The code below is contrived to show the problem; I do need to do something similar in actual code.)
type F = Int => Int
val f: Int => Int = identity
val g1: F => F = identity
val g2: F => F = (identity _).asInstanceOf[F => F]
println("f = " + f)
println("g1 = " + g1)
println("g2 = " + g2)
val h1: Int => Int = g1(f: Int => Int)
val h2: Int => Int = g2(f: Int => Int)
Here is the output of the code:
f = doodle.Bug$$$Lambda$7/1836797772#4b53f538
g1 = doodle.Bug$$$Lambda$8/1383547042#543e710e
g2 = doodle.Bug$$$Lambda$9/3213500#57f23557
Here is the exception:
java.lang.ClassCastException: doodle.Bug$$$Lambda$7/1836797772 cannot be cast to scala.runtime.Nothing$
I find it particularly strange that casting g2 results in an implicit cast on f...

Wild guess: ammonite suggest that this:
(identity _)
has a type of:
Nothing => Nothing
Scala might remember this fact. Maybe because of specialization or (more likely) maybe Eta expansion of identity creates a closure that remember that it IS Nothing => Nothing function that underneath call identity.
In such situation, when you use it in context where JVM does an actual check (so not at the moment you run asInstanceOf, but during the application), then casting fails and you see the exception.
identity[F] _
works as expected without exception.

Related

Can someone please expand the following shorthand and explain how this works

I'm looking at this sample code and after entering it in the scala repl I can see how it works.
val twice: Int => Int =
x => x * 2
This is similar:
val parse: String => Option[Int] =
s => if(s.matches("-?[0-9]+")) Some(s.toInt) else None
Can someone please deconstruct the above method and explain how this works?
I can see the name twice or parse, followed by the type which is Int => Int or String => Option[Int].
Now in the 2nd line of both functions you have a variable x or s. I can only assume this is the parameter.
Also if you can expand on what scala features allow a function to be written like this.
Thanks!
The expected type of value
x => x * 2
is
Int => Int
which de-sugars to
Function1[Int, Int]
hence function definition
val twice: Int => Int = x => x * 2
is equivalent to
val twice: Function1[Int, Int] = new Function1[Int, Int] {
override def apply(x: Int) = x * 2
}
as per SLS 6.3 Anonymous Functions.

Scala lambda function not resolved when declares the type of parameter?

when defining method in Scala, I found this
def method1: Int => Int = (j: Int) => j // works
def method2: Int => Int = j => j // works
def method3: Int => Int = j: Int => j // error
def method4: Int => Int = {j: Int => j} // works
Can anyone explain why method3 does not work? Is there any ambiguity in it?
One possible explanation is indeed that this restriction avoids ambiguity: x: A => B could be understood as an anonymous function that takes a parameter x of type A and returns the object B. Or it could be understood as "casting" a variable x to the type A => B. It is very rare that both of these would be valid programs, but not impossible. Consider:
class Foo(val n: Int)
val Foo = new Foo(0)
val j: Int => Foo = new Foo(_)
def method1: Int => Foo = (j: Int) => Foo
def method2: Int => Foo = j: Int => Foo
println(method1(1).n)
println(method2(1).n)
This actually compiles and prints:
0
1
All of these variants are covered by Anonymous Functions section of the specification. The relevant part is
In the case of a single untyped formal parameter, (x) => e
can be abbreviated to
x => e. If an anonymous function (x : T) => e
with a single typed parameter appears as the result expression of a block, it can be abbreviated to
x: T => e.
In method3, the function isn't the result expression of a block; in method4 it is.
EDIT: oops, presumably you meant why the limitation is there. I'll leave this answer for now as stating what the limitation is exactly, and remove it if anyone gives a better answer.

Executing and getting return value of a function wrapped in a context?

I have a function in a context, (in a Maybe / Option) and I want to pass it a value and get back the return value, directly out of the context.
Let's take an example in Scala :
scala> Some((x:Int) => x * x)
res0: Some[Int => Int] = Some(<function1>)
Of course, I can do
res0.map(_(5))
to execute the function, but the result is wrapped in the context.
Ok, I could do :
res0.map(_(5)).getOrElse(...)
but I'm copy/pasting this everywhere in my code (I have a lot of functions wrapped in Option, or worst, in Either...).
I need a better form, something like :
res0.applyOrElse(5, ...)
Does this concept of 'applying a function in a concept to a value and immediatly returning the result out of the context' exists in FP with a specific name (I'm lost in all those Functor, Monad and Applicatives...) ?
You can use andThen to move the default from the place where you call the function to the place where you define it:
val foo: String => Option[Int] = s => Some(s.size)
val bar: String => Int = foo.andThen(_.getOrElse(100))
This only works for Function1, but if you want a more generic version, Scalaz provides functor instances for FunctionN:
import scalaz._, Scalaz._
val foo: (String, Int) => Option[Int] = (s, i) => Some(s.size + i)
val bar: (String, Int) => Int = foo.map(_.getOrElse(100))
This also works for Function1—just replace andThen above with map.
More generally, as I mention above, this looks a little like unliftId on Kleisli, which takes a wrapped function A => F[B] and collapses the F using a comonad instance for F. If you wanted something that worked generically for Option, Either[E, ?], etc., you could write something similar that would take a Optional instance for F and a default value.
You could write something like applyOrElse using Option.fold.
fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B
val squared = Some((x:Int) => x * x)
squared.fold {
// or else = ifEmpty
math.pow(5, 2).toInt
}{
// execute function
_(5)
}
Using Travis Browns recent answer on another question, I was able to puzzle together the following applyOrElse function. It depends on Shapeless and you need to pass the arguments as an HList so it might not be exactly what you want.
def applyOrElse[F, I <: HList, O](
optionFun: Option[F],
input: I,
orElse: => O
)(implicit
ftp: FnToProduct.Aux[F, I => O]
): O = optionFun.fold(orElse)(f => ftp(f)(input))
Which can be used as :
val squared = Some((x:Int) => x * x)
applyOrElse(squared, 2 :: HNil, 10)
// res0: Int = 4
applyOrElse(None, 2 :: HNil, 10)
// res1: Int = 10
val concat = Some((a: String, b: String) => s"$a $b")
applyOrElse(concat, "hello" :: "world" :: HNil, "not" + "executed")
// res2: String = hello world
The getOrElse is most logical way to do it. In regards to copy/pasting it all over the place - you might not be dividing your logic up on the best way. Generally, you want to defer resolving your Options (or Futures/etc) in your code until the point you need to have it unwrapped. In this case, it seems more sensible that your function takes in an an Int and returns an Int, and you map your option where you need the result of that function.

Declare a function using def or var in Scala

I'm trying to figure out the difference between def and var/val when declaring a function in Scala.
Say we have a function:
scala> def f(x: Int) = { x * 2 }
f: (x: Int)Int
And another function g:
scala> var g = (x:Int) => x*2
g: Int => Int = <function1>
Apparently they are the same in the following way:
scala> f(2)
res0: Int = 4
scala> g(2)
res1: Int = 4
However, I could do
g = f
g: Int => Int = <function1>
but not
scala> f = g
<console>:13: error: missing arguments for method f;
follow this method with `_' if you want to treat it as a partially applied function
val $ires6 = f
^
<console>:10: error: reassignment to val
f = g
^
Question 1: why does this happen? I'm guessing that def maps to val.
Question 2: if I use val instead of var in declare g, are they equivalent? If not, what is the difference then?
I then try:
scala> def three( timetwo:(Int) => Int ) = { timetwo(3) }
three: (timetwo: Int => Int)Int
scala> three(g)
res47: Int = 6
scala> three(f)
res48: Int = 6
Question 3: does it mean (x: Int)Int is the same as Int => Int = <function1>? If so, is there some situation that we should favor one over the other?
Things is getting wired with the _ (underscore),
scala> three(f _)
res49: Int = 6
scala> three(g _)
<console>:11: error: type mismatch;
found : () => Int => Int
required: Int => Int
three(g _)
^
Question 4: why does this happen? What's the usage of _(underline) in Scala?
why does this happen? I'm guessing that def maps to val.
def is a method (in JVM terms) so it doesn't make sense to assign it.
The parser is then confused and it ultimately tries to save the day by interpreting the assignment f = g as
val $ires6 = f
f = g
Both statements are illegal, so you get two errors:
you can't assign a method to a val without an explicit type annotation or a _ expansion - see below)
you can't reassign a val (in case you are wondering, $ires6 is a fresh val introduced by the REPL)
if I use val instead of var in declare g, are they equivalent? If not, what is the difference then?
The difference is that val cannot be reassigned (i.e. it's a constant reference), whereas var can (i.e. it's a mutable reference).
More on the subject here: What is the difference between a var and val definition in Scala?
does it mean (x: Int)Int is the same as Int => Int = ? If so, is there some situation that we should favor one over the other?
Methods and functions are not the same, although the compiler does its best to make you believe they are, through a transformation called eta-expansion. In some cases such transformation can be performed automatically, in some others you need to be explicit and trigger it with a trailing _.
In your specific example (passing a method where a function is expected) the expansion can been performed automatically.
You can read this Q/A for a more in-depth discussion about which style to prefer.
why does this happen? What's the usage of _(underline) in Scala?
The underscore (_) has many uses in scala, one of which is the one I mentioned before, i.e. triggering the eta expansion of a method into a function.
That's a special syntax for methods, so you simply can't apply it to a function, as it would make no sense.
That's why you can do f _ (which will turn the f method into a function), but you can't do g _ (since g it's already a function).

Difficulty understanding function syntax

I can understand this:
scala> def f(i: Int) = "dude: " + i
f: (i: Int)java.lang.String
scala> f(3)
res30: java.lang.String = dude: 3
It defines a function f that takes an int and returns a string that is of the form dude: + the int that is passed in.
Now the same function can be specified like this:
val f: Int => String = x => "dude: " + x
scala> f(3)
res31: String = dude: 3
Why do we need two =>
What does String = x mean? I thought that when you want to define something in Scala you'd do x:String?
You should parse it as
val (f: Int => String) = (x => "dude: " + x)
So it specifies that f has type (Int => String) and is defined as an anonymous function which takes an Int parameter (x) and returns a String.
Only to clarify a bit. def statements defines methods, not functions.
Now, for the function. You could have written it this way:
val f: (Int => String) = x => "dude: " + x
And it could be read as "f is a function from Int to String". So, answering your question, a => in a type position mean function from type to type, while => in a value position means takes parameter identifier and returns expression.
Further, it can also rely on the type inferrer:
val f = (x:Int) => "dude: " + x
Both Lee and pedrofurla gave excellent answers. I'll also add that if you want your method to be converted to a function (for passing as a parameter, use as a partially applied function, etc), you can use the magic underbar:
def foo(i: Int) = "dude: " + x
val bar = foo _ // now you have a function bar of type Int => String