Scala subclass pattern match - scala

I'm trying to run code from the book "Functional Programming in Scala" which seems to be made for an older version of scala (download from here). tmp.scala:
sealed trait Option[+A]
case class Some[+A](get: A) extends Option[A]
case object None extends Option[Nothing]
trait Option[+A] {
/* returns None if None, or function applied to the some object */
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(a) => Some(f(a))
}
}
The errors this throws are:
$ scala
Welcome to Scala 2.12.0-20161021-070700-8684ae8 (OpenJDK 64-Bit Server VM, Java 1.8.0_112).
scala> :load tmp.scala
tmp.scala:17: error: pattern type is incompatible with expected type;
found : None.type
required: Option[A]
case None => None
^
tmp.scala:17: error: type mismatch;
found : None.type
required: Option[B]
case None => None
^
tmp.scala:18: error: constructor cannot be instantiated to expected type;
found : Some[A(in class Some)]
required: Option[A(in trait Option)]
case Some(a) => Some(f(a))
^
tmp.scala:18: error: type mismatch;
found : Some[B]
required: Option[B]
case Some(a) => Some(f(a))
^
I tried all sorts of codefu on this, but to no avail, it seems like it's not detecting the subclasses properly due to outdated syntax?

Use :paste file.scala, which pastes the content, instead of :load file.scala, which interprets each line.

Related

Scala: Implementing a generic fold

I don't understand why thid fold doesn't compile. Could anyone give me a clue?
sealed trait ListG[A] {
def fold[A,B](end: B, f: (A,B) => B): B = this match {
case End() => end
case Cons(hd,tl) => f(hd, tl.fold(end,f))
}
}
Error:(20, 28) type mismatch;
found : hd.type (with underlying type A)
required: A
case Cons(hd,tl) => f(hd, tl.fold(end,f))
^
final case class EndA extends ListG[A]
final case class Cons[A](hd:A, tl:ListG[A]) extends ListG[A]
You're shadowing type parameter A of ListG when you define an additional type parameter A on the fold function.
Adding type ascription appears to fix the problem.
case Cons(hd:A, tl) => ...
^^
There is a warning about type erasure but it does compile and appears to run.

What does not compile?

I have a trait as follow:
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(a) => Some(f(a))
}
}
case class Some[+A](get: A) extends Option[A]
case object None extends Option[Nothing]
When I try to compile I've got following error:
scala> :load "src/Option.scala"
Loading src/Option.scala...
src/Option.scala:17: error: pattern type is incompatible with expected type;
found : None.type
required: Option[A]
case None => None
^
src/Option.scala:17: error: type mismatch;
found : None.type
required: Option[B]
case None => None
^
src/Option.scala:18: error: constructor cannot be instantiated to expected type;
found : Some[A(in class Some)]
required: Option[A(in trait Option)]
case Some(a) => Some(f(a))
^
src/Option.scala:18: error: type mismatch;
found : Some[B]
required: Option[B]
case Some(a) => Some(f(a))
^
src/Option.scala:11: error: illegal inheritance from sealed class Option
case class Some[+A](get: A) extends Option[A]
^
src/Option.scala:11: error: illegal inheritance from sealed class Option
case object None extends Option[Nothing]
Why?
I am new in scala world and can not differ if the map is function or a method? How can I use map?

scala pattern matching in trait

sealed trait Option_40to49[+A] {
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(x) => Some(f(x))
}
}
I work in eclipse, it underlined None with the next error:
pattern type is incompatible with expected type; found : None.type required: packageName.Option_40to49[A]
and the similar with Some(x)
constructor cannot be instantiated to expected type; found : Some[A(in class Some)] required: packageName.Option_40to49[A(in trait Option_40to49)]
Why I have this problem? How to fix it?
By using this in your pattern match you're referring to your Option_40to49, but since you haven't implemented None or Some the compiler doesn't know what these are
Simple versions of these aren't that hard to implement yourself. Note, you'll also want to change your output for map to Option_40to49
sealed trait Option_40to49[+A] {
def map[B](f: A => B): Option_40to49[B] = this match {
case None => None
case Some(x) => Some(f(x))
}
}
case class Some[A](x: A) extends Option_40to49[A]
case object None extends Option_40to49[Nothing]

Implementing map on Option

Working more on FP in Scala examples, I tried to implement the Option trait's map function as follows:
sealed trait MyOption[+A] {
def map[B](f: A => B): Option[B] = this match {
case Some(a) => Some(f(a))
case _ => None
}
}
However, compile-time errors show, if I understand correctly, that I'm not pattern-matching correctly for the case of Some(A). Using pattern matching, how can I write the first case to get Some(A) values to match?
>scalac MyOption.scala
MyOption.scala:3: error: constructor cannot be instantiated to expected type;
found : Some[A(in class Some)]
required: MyOption[A(in trait MyOption)]
case Some(a) => Some(f(a))
^
MyOption.scala:3: error: not found: value a
case Some(a) => Some(f(a))
^
two errors found
You are trying to define map in terms of Some and None which are subclasses of the Scala-provided Option trait, rather than in terms of subclasses of your own trait. Try something like:
sealed trait MyOption[+A] {
import MyOption._
def map[B](f: A => B): MyOption[B] = this match {
case MySome(a) => MySome(f(a))
case _ => MyNone
}
}
object MyOption {
case class MySome[+A](a: A) extends MyOption[A]
case object MyNone extends MyOption[Nothing]
}

Can't even try to load a class in Scala

This is one of those times where you go, What do you mean, it doesn't compile?
That's not a rhetorical question: What's the shortest or idiomatickest fix? For bonus points, why is it necessary?
scala> import scala.util.Try
import scala.util.Try
scala> Try { getClass.getClassLoader loadClass "scala.util.Try" }
I hope this doesn't give the game away, but here's the message:
<console>:9: error: type mismatch;
found : Class[_]
required: Class[?0(in value res0)] where type ?0(in value res0)
Note: Any >: ?0, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
Try { getClass.getClassLoader loadClass "scala.util.Try" }
By "investigate", do they mean like basic research, or just apply techniques already available in the literature?
I'm still waiting for that error message that concludes, "Left as an exercise for the reader."
Update:
This is an exercise for Scala 2.10.
As usual, all good things come to those that wait:
apm#mara:~/tmp$ skala
Welcome to Scala version 2.11.0-20130622-103744-990c2b024a (OpenJDK 64-Bit Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.language.existentials
import scala.language.existentials
scala> import scala.util.Try
import scala.util.Try
scala> Try { getClass.getClassLoader loadClass "scala.util.Try" }
res0: scala.util.Try[Class[?0]] forSome { type ?0 } = Success(class scala.util.Try)
This must surely be a duplicate question. Maybe someone can point it out, or exactly how type inference is not doing what comes naturally here.
Someone left an answer (which seems to have disappeared?) with a helpful link to MacIver on existential types. Possibly, I also need help from MacGyver.
Here are some variants I tried on the way to the forum.
package classy
import scala.util._
class Foo
object Test {
/* DNC
def loadTry(n: String, loader: ClassLoader) = Try { loader loadClass n }
def loadTry(n: String, loader: ClassLoader): Try[Class[_]] = Try { loader loadClass n }
*/
def main(args: Array[String]) {
val cl = getClass.getClassLoader
println(loadTry("classy.Foo", cl))
println(loadTry("classy.Bar", cl))
println(cl loadClass "classy.Foo")
println(loadOpt("classy.Foo", cl))
println(loadTryAgain("classy.Foo", cl))
println(loadTryYetAgain("classy.Foo", cl))
}
def loadOpt(n: String, loader: ClassLoader): Option[Class[_]] =
try Some(loader loadClass n) catch {
case _: Exception => None
}
def loadTryAgain(n: String, loader: ClassLoader): Try[Class[_]] = {
val res: Option[Class[_]] = try Some(loader loadClass n) catch {
case _: Exception => None
}
res match {
case None =>
Failure(new RuntimeException(s"Warning: class not found: ${n})"))
case Some(x) =>
Success(x)
}
}
def loadTryYetAgain(n: String, loader: ClassLoader): Try[Class[_]] = {
val res = try loader loadClass n catch {
case _: Exception => null
}
res match {
case null =>
Failure(new RuntimeException(s"Warning: class not found: ${n})"))
case x =>
Success(x)
}
}
def loadTry(n: String, loader: ClassLoader) =
Try[Class[_]] {
loader loadClass n
} recoverWith {
case e: Exception =>
Failure(new RuntimeException(s"Warning: class not found: ${n} (${e.getMessage})"))
}
}
the Try is causing it. for me in scala 2.10.0:
scala> import scala.util.Try
scala> val typeName = "scala.util.Try"
error:
scala> Try(Class.forName(typeName))
<console>:10: error: type mismatch;
found : Class[_]
required: Class[?0(in value res1)] where type ?0(in value res1)
Note: Any >: ?0, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
Try(Class.forName(typeName))
^
no error:
scala> Try[Class[_]](Class.forName(typeName))
res2: scala.util.Try[Class[_]] = Success(class scala.util.Try)
catching also has the same problem:
scala> import scala.util.control.Exception._
scala> catching(classOf[Throwable]) opt Class.forName(typeName)
<console>:13: error: type mismatch;
found : Class[_]
required: Class[?0(in value res4)] where type ?0(in value res4)
Note: Any >: ?0, but Java-defined class Class is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
catching(classOf[Throwable]) opt Class.forName(typeName)