实现flatMap函数

时间:2012-12-29 13:49:03

标签: scala

免责声明:这是家庭作业的一部分。 我想为自定义List对象实现flatMap。我已经成功实现了map,但是我遇到了flatMap的问题。我不知道如何压缩我从地图中获得的列表列表。我不知道我是否真的应该使用地图。

trait List[+A] {
  /** The first element */
  def head: A
  /** The rest of the elements */
  def tail: List[A]
  def flatMap[B](f: A => List[B]): List[B]
  def map[B](f: A => B): List[B]

  // Concatenate two lists
  def concat[B >: A](that: List[B]): List[B] = this match {
    case Empty => that
    case NonEmpty(head, tail) => NonEmpty(head, tail concat that)
  }
}

case object Empty extends List[Nothing] {
  def head = throw new UnsupportedOperationException("Empty.head")
  def tail = throw new UnsupportedOperationException("Empty.tail")
  def flatMap[B](f: Nothing => List[B]): List[B] = Empty
  def map[B](f: Nothing => B): List[B] = Empty

  override def toString = "Empty"
}

case class NonEmpty[A](head: A, tail: List[A]) extends List[A] {

  def map[B](f: A => B): List[B] = {

    NonEmpty(f(head), tail.map(f))

  }
def flatMap[B](f: A => List[B]): List[B] = {
    val a = this.map(f)
    for (x <- a; y <- x) yield y
  }
}

2 个答案:

答案 0 :(得分:3)

因为这是一个家庭作业,我不想给你一个完整的解决方案,只是一些提示。

  1. 您不需要map来实施flatMap(实际上反过来说更容易)
  2. 您拥有所需的一切(flatMap采用的函数返回List[B]List已定义concat
  3. 首先实施flatMap Empty; - )

答案 1 :(得分:2)

您必须为长度为n的列表编写flatMap。尝试解决它,假设您已经为长度为n-1的列表解决了它。如果你能做到这一点,那么你就解决了这个问题,因为n =&gt; n-1 =&gt; ... =&gt; 1 =&gt; 0,对于0,你已经有了解决方案。

这种思路适合你的List,因为它是一种递归类型。

你已经用map做过这个,用flatMap做同样的事。这两个函数都是从List [A]到List [B]的转换,唯一的区别是它们可以使用的工具,map有一个将A转换为B的函数,而flatMap有一个将A转换为List的函数[B]