2
votes

I'm working through Functional Programming in Scala (first edition) and coming across an error when working through a solution to the first exercise in Chapter 4: Handling errors without exceptions.

The chapter rebuilds the Option type using the following structure:

sealed trait Option[+A]
case class Some[+A](get: A) extends Option[A] 
case object None extends Option[Nothing]

The first exercise instructs the reader to implement the following methods on the Option type:

trait Option[+A] {
def map[B](f: A => B): Option[B]
def flatMap[B](f: A => Option[B]): Option[B] 
def getOrElse[B >: A](default: => B): B
def orElse[B >: A](ob: => Option[B]): Option[B] 
def filter(f: A => Boolean): Option[A]
}

When loading the solution verified by the answer key for the book via the scala REPL

sealed trait Option[+A] {
  def map[B](f: A => B): Option[B] = this match {
    case Some(a) => Some(f(a))
    case None    => None
  }
}
case class Some[+A](get: A) extends Option[A]
case object None extends Option[Nothing]

I receive a compilation error:

scala> :load ErrorHandling.scala
val args: Array[String] = Array()
Loading ErrorHandling.scala...

           case Some(a) => Some(f(a))
                ^
ErrorHandling.scala:3: 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))
                               ^
ErrorHandling.scala:3: error: type mismatch;
        found   : Some[B]
        required: Option[B]

           case None    => None
                ^
ErrorHandling.scala:4: error: pattern type is incompatible with expected type;
        found   : None.type
        required: Option[A]

           case None    => None
                           ^
ErrorHandling.scala:4: error: type mismatch;
        found   : None.type
        required: Option[B]

Given None and Some extend Option, I'm not sure where the type mismatch is arising.

Any help would be greatly appreciated!

1
Seems to work fine in scastie. - Guru Stron
Another suggestions - Don't learn Scala by using REPL. This thing has many instances where it behaves very differently then actual Scala application. Use REPL only for very basic experiments. - sarveshseri
@sarveshseri Good to note... what would be your preferred avenue? Calling methods through a main method? - Robert Maples

1 Answers

4
votes

:load interprets lines in the file one-by-one, as if they were typed. This breaks your case horribly because the lines you type into the REPL act as if they were all in different files; in particular, earlier lines cannot see later ones. So the Some and None in the definition of Option are resolved to the standard ones, not the ones defined later, and sealed makes those definitions illegal because they are not in the same "file."

Use :paste

scala> :paste ErrorHandling.scala
Pasting file ErrorHandling.scala...
trait Option
class Some
object None

scala>