【发布时间】:2015-02-26 22:13:24
【问题描述】:
我是 FP 和 Scala 的新手,正在阅读《Scala 中的函数式编程》一书。第 4 章中的一个练习要求我们编写一个名为sequence 的函数,它将List[Option[A]] 转换为Option[List[A]]。这里的Option 是Scala 库提供的Option 的重新实现。这是所需的代码。
trait Option[+A] {
/* Function to convert Option[A] to Option[B] using the function passed as an argument */
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(v) => Some(f(v))
}
/* Function to get the value in `this` option object or return the default value provided. Here,
* `B >: A` denotes that the data type `B` is either a super-type of `A` or is `A`
*/
def getOrElse[B >: A](default: => B): B = this match {
case None => default
case Some(v) => v
}
/* Used to perform (nested) operations on `this` and aborts as soon as the first failure is
* encountered by returning `None`
*/
def flatMap[B](f: A => Option[B]): Option[B] = {
map(f).getOrElse(None)
}
}
case class Some[+A](get: A) extends Option[A] // used when the return value is defined
case object None extends Option[Nothing] // used when the return value is undefined
现在我尝试了很多,但我不得不查找写sequence的解决方案,即,
def sequence[A](l: List[Option[A]]): Option[List[A]] = l match {
case Nil => Some(Nil) // Or `None`. A design decision in my opinion
case h :: t => h.flatMap(hh => sequence(t).map(hh :: _))
}
我只是想确保我正确理解了解决方案。所以这是我的问题。
- 我对@987654329@ 的返回值的直觉是否正确?这真的是一个设计决策还是一种方式比另一种更好?
- 对于
case h :: t,这是我理解的。我们首先将值h传递给flatMap中的匿名函数(如hh),该函数递归调用sequence。sequence的此递归调用返回一个Option,将Options 封装在t中。我们在这个返回值上调用map并将h传递给匿名函数(作为hh),然后它创建一个新的List[A],递归调用返回的列表作为尾部,h作为头部.然后通过调用Some将该值封装在Option中并返回。
我对第二部分的理解正确吗?如果是,有没有更好的解释方式?
【问题讨论】:
标签: scala