【问题标题】:implementing List tail method in Scala在 Scala 中实现 List tail 方法
【发布时间】:2022-01-01 20:05:59
【问题描述】:

我正在自学 Scala。特别是,我正在关注 Chiusano 等人的Scala 中的函数式编程一书。第 3 章介绍了一个链表的实现:

sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]

object List{
  def sum(ints: List[Int]): Int = ints match{
  case Nil => 0
  case Cons(x, xs) => x + sum(xs)
  }

def product(ds: List[Double]): Double = ds match {
  case Nil => 1.0
  case Cons(0.0, _) => 0.0
  case Cons(x, xs) => x*product(xs)
  }      

def apply[A](as: A*): List[A] =
  if (as.isEmpty) Nil
  else Cons(as.head, apply(as.tail: _*))
}

并要求您实现函数 tail,它应该返回一个包含除第一个之外的所有值的列表。我通过以下方式实现了它:

def tail(ints: List[Int]): List[Int] = ints match {
  case Cons(x, xs) => xs
  }

(部分原因是我不知道如何实现传递列表为 Nil 的情况)。 但是,当我在List(1,2,3) 上对其进行测试时,会返回以下内容:

Cons(2,Cons(3,Nil))

代替:

List(2, 3)  

这是我所期待的。另外我用的是intellij,IDE不让我写List(1,2,3).tail,只能写tail(List(1,2,3))

谁能告诉我我做错了什么?为什么我的尾部实现给了我如此奇怪的返回值?为什么 IDE 不让我写 List(1,2,3).tail?列表传递为Nil的情况如何实现?

【问题讨论】:

  • Cons(2,Cons(3,Nil)) [2; 3]列表(即[1; 2; 3]tail,即Cons(1, Cons(2,Cons(3,Nil))))。您看到的字符串表示是case classes 的默认表示。您可以覆盖它,例如在 stdlib 中。至于为什么你不能做List(...).tail,那是因为你的实现是一个函数(将列表作为参数),而不是你的类List上的方法。
  • tail of empty List 抛出异常

标签: scala linked-list functional-programming


【解决方案1】:

为什么 IDE 不让我写 List(1,2,3).tail

您编写的是一个独立的方法,它将List 作为传入参数。如果您想要让List 返回它自己的tail,那么您实际上已经完成了一半。

Cons 已经有一个tail 成员,您只需将其提升为List 定义并给Nil 一个合理的实现。

sealed trait List[+A] {
  val tail: List[A]
}
case object Nil extends List[Nothing] {
  lazy val tail =
    throw new UnsupportedOperationException("tail of empty List")
}
case class Cons[+A](head: A, tail: List[A]) extends List[A]

【讨论】:

    猜你喜欢
    • 2019-04-17
    • 1970-01-01
    • 2023-03-25
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多