Scala: вернуть заголовок списка, но пустой список не может вернуть ноль

Я только начинаю изучать Scala, и у меня возникли небольшие проблемы с функцией головы. Я хочу вернуть первый элемент из списка элементов А. Но в случае с Нилом я не знаю, что вернуть. Функция ожидает 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

    }
}

Любая помощь, чтобы понять проблему, очень ценится.

2 ответа

Решение

Вариант на помощь

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 в стандартной библиотеке

Есть этот странный тип, называемый Nothing, Nothing это подтип всего. Особенно, Nothing это подтип A (без разницы A является). Вы не можете создавать какие-либо значения типа Nothing (этот тип необитаем). Но throw Ключевое слово ведет себя так, как если бы оно "вернулось"Nothing, Если операция бессмысленная, то вы можете создать исключение с описательным сообщением об ошибке:

case Cons(h, _) => h
case Nil => throw new NoSuchElementException("`head` called on `Nil`")
Другие вопросы по тегам