【问题标题】:Scala: Return head of list but empty list can't return NilScala:返回列表头但空列表不能返回 Nil
【发布时间】:2019-02-04 16:24:24
【问题描述】:

我刚刚开始学习 Scala,但我在使用 head 函数时遇到了一些麻烦。我想从 A 元素列表中返回第一个元素。但在 Nil 的情况下,我不知道返回什么。该函数需要 A,但由于 A 是抽象的并且可以是任何东西,我不知道要返回什么。

当我将一个空列表传递给我的 tails 函数时,返回 Nil 工作正常。

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 tail[A](xs: List[A]): List[A] = {
                 xs match {
                   case Cons(_, ys) => ys
                   case Nil         => Nil
             }
         }

         def head[A](as: List[A]): A = {
                 as match {
                   case Cons(b, _) => b
                   case Nil         => Nil
             }
    }
}

object e31 {
    def main(args: Array[String]): Unit = {
                  val ex3: List[Int] = Cons(1, Cons(2, Nil))
                  val ex2: List[Int] = Nil;

                  println(List.sum(ex3)) //3
                  println(List.tail(ex2)) //Nil
                  println(List.tail(ex3)) //cons(2, Nil)
                  //println(List.head(ex3)) //doesn't work

    }
}

非常感谢任何有助于理解问题的帮助。

【问题讨论】:

    标签: scala list functional-programming traits


    【解决方案1】:

    救援选项

    def head[A](as: List[A]): Option[A] = as match {
     case Cons(b, _) => Some(b)
     case Nil        => None
    }
    

    使head 返回Option。使用Option,您可以传达有时答案不可用或无效。例如:在这种情况下,当列表为空时head 操作没有意义。因此,在这种情况下,我们返回 None 值。否则当列表不为空时,我们返回Some 有效结果。

    为了传达结果并不总是可用,我们使用Option 作为返回类型

    编译错误

    下面的代码会导致编译错误,因为您的返回类型是A,但您实际上返回的是Nil List[A] 的类型

    def head[A](as: List[A]): A = as match {
     case Cons(b, _) => b
     case Nil         => Nil // expected A found: List[A]
    }
    

    注意这个函数(返回选项的头(上面声明的))在标准库中被称为headOption

    【讨论】:

    • 不,返回Option的东西通常称为headOption...
    • @AndreyTyukin 我知道。 head 是 OP 编写的函数。 (它是一个自定义函数)。我只是要求 OP 更改返回类型。 OP可以把函数名改成headOption
    【解决方案2】:

    有一种奇怪的类型叫做NothingNothing 是一切的子类型。特别是,NothingA 的子类型(无论A 是什么)。你不能产生任何Nothing 类型的值(这种类型是uninhabited)。但是throw 关键字的行为就好像它会“返回”Nothing。如果操作是无意义的,那么你可以做的就是抛出一个带有描述性错误消息的异常:

    case Cons(h, _) => h
    case Nil => throw new NoSuchElementException("`head` called on `Nil`")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 2020-06-12
      • 2019-08-18
      相关资源
      最近更新 更多