Scala在实施Option方面的选择

时间:2014-09-22 19:45:19

标签: scala

如何在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
  }

我如何在OOP世界中承担它:

  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))
  }

后者出了什么问题?

Functional programming in Scalamatch特征中使用Option[A],这是第三种方式(看起来像Haskell,但为什么?)为什么不利用子类型多态?

更新:我提到的第三种方式:

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] {
}

2 个答案:

答案 0 :(得分:1)

我不确定您是否打算这样做,但是您遗漏了isEmptyget的声明,这些声明是任何想要检查任意Option内容的人所需要的无需向下转换为Some。由于这两个方法都需要由两个子类定义,并且因为map可以用它们来定义,我认为推理是在一个地方定义map最好利用它其他方法的子类实现,而不是在三个地方定义map

答案 1 :(得分:0)

我想,因为scala支持功能和命令,并且它瞄准java程序,这是让它们更舒适的东西之一。
来自java程序员

val opt: Option[String] = ???
if (!opt.isEmpty) {
  //do something with opt.get
} else {
  //do some default...
}

可能比功能方式更容易理解(即使使用getOrElse)。

@Victor Moroz写了一篇关于使用模式匹配而不是this match { None => default_val; Some(v) => v }的评论 除了新功能世界的程序员更难以阅读之外,这将花费更多,因为Option的用途很多,而且instanceOf的成本高于简单的if。