How it's done in Scala:
sealed trait Option[+A] {
def get: A
def isEmpty: Boolean
def map[B](f: A => B): Option[B] =
if (isEmpty) None else Some(f(this.get))
}
object None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}
case class Some[+A](x: A) extends Option[A] {
def isEmpty = false
def get = x
}
How I would assume it in OOP world:
sealed trait Option[+A] {
def map[B](f: A => B): Option[B]
}
object None extends Option[Nothing] {
def map[B](f: Nothing => B): Option[B] = this
}
case class Some[+A](get: A) extends Option[A] {
def map[B](f: A => B): Option[B] = Some(f(get))
}
What's wrong with the latter?
Functional programming in Scala is using match
in Option[A]
trait, which is the third way (looks like Haskell, but why?) Why not utilize subtype polymorphism?
UPDATE: Third way I mentioned:
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(a) => Some(f(a))
}
}
object None extends Option[Nothing] {
}
case class Some[+A](get: A) extends Option[A] {
}