Scala: вернуть заголовок списка, но пустой список не может вернуть ноль - PullRequest
0 голосов
/ 29 августа 2018

Я только начинаю изучать 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 ]

0 голосов
/ 29 августа 2018

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

case Cons(h, _) => h
case Nil => throw new NoSuchElementException("`head` called on `Nil`")
0 голосов
/ 29 августа 2018

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

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

...