Scala несоответствие типов, не удается разрешить символ A, тип шаблона несовместим с ожидаемым типом - PullRequest
0 голосов
/ 08 января 2020

Я работаю над написанием класса Stream в главе 5 Функционального программирования в Scala, я знаю, что решения в сети, но это не помогает мне. Я столкнулся с той же проблемой с предыдущей главой, в которой был написан класс List.

Я был настолько разочарован, что на самом деле скопировал копию из решения на мой лист Scala, и все еще та же проблема.

I Я подумал, может быть, это из-за названия (уже есть Список и Поток), не похоже на разумную идею назвать их так, поэтому я изменил его, не помогло.

Может быть, это что-то делать с Intellij (я использую IntelliJ IDEA), я делаю упражнения на Scala рабочих листах. Но я не могу найти что-либо об этой проблеме в отношении IDE.

Вот что у меня есть до сих пор:

sealed trait StreamRED[+A]
case object Empty extends StreamRED[Nothing]
case class Cons[+A](h: () => A, t: () => StreamRED[A]) extends StreamRED[A]

object StreamRED {
  def cons[A](hd: => A, tl: => StreamRED[A]): StreamRED[A] = {
    lazy val head = hd
    lazy val tail = tl
    Cons(() => head, () => tail)
  }
  def empty[A]: StreamRED[A] = Empty

  def apply[A](as: A*): StreamRED[A] =
    if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))

  def headOption: Option[A] = this match {
    case Empty => None
    case Cons(h,t) => Some(h())
  }

  def toList: List[A] = {
    @annotation.tailrec
    def go(s: StreamRED[A], acc: List[A]): List[A] = s match {
      case Cons(h,t) => go(t(), h() :: acc)
      case _ => acc
    }
    go(this, List()).reverse
  }
}

Я получаю следующие ошибки:

«Не удается разрешить символ A» для A в Option [A] (в методе headOption) и List [A] и StreamRED [A] (в toList)

«Несоответствие типов. Обязательный параметр: StreamRED [Любой], Найдено: StreamRED.type "on this в toList.

" Тип шаблона несовместим с ожидаемым типом. Найдено: Empty.type, обязательный: StreamRED.type "для параметра Empty in headOption.

Новый для Scala, новый для IntelliJ, новый для статически типизированных языков, новый для FP. Любые объяснения и рекомендации для хороших материалов для чтения высоко ценится.

1 Ответ

1 голос
/ 08 января 2020

Две функции toList и headOption не могут быть определены в сопутствующем объекте StreamRED.

Если вы определяете их непосредственно в trait, это работает:


sealed trait StreamRED[+A] {

  def headOption: Option[A] = this match {
    case Empty => None
    case Cons(h,t) => Some(h())
  }

 def toList: List[A] = {
    @annotation.tailrec
    def go(s: StreamRED[A], acc: List[A]): List[A] = s match {
      case Cons(h,t) => go(t(), h() :: acc)
      case _ => acc
    }
    go(this, List()).reverse
  } 
}

case object Empty extends StreamRED[Nothing]
case class Cons[+A](h: () => A, t: () => StreamRED[A]) extends StreamRED[A]

object StreamRED {
  def cons[A](hd: => A, tl: => StreamRED[A]): StreamRED[A] = {
    lazy val head = hd
    lazy val tail = tl
    Cons(() => head, () => tail)
  }
  def empty[A]: StreamRED[A] = Empty

  def apply[A](as: A*): StreamRED[A] =
    if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
}

Слово предупреждения: Совпадение с шаблоном на this - это , мне кажется плохой практикой. Вы точно знаете, что такое this. Вместо этого реализуйте функции в Empty и Cons.

Сделайте это вместо:

sealed trait StreamRED[+A] {
  def headOption: Option[A]
  def toList: List[A]
}

case object Empty extends StreamRED[Nothing] {
  def headOption: Option[Nothing] = None
  def toList: List[Nothing] = List()
}


case class Cons[+A](h: () => A, t: () => StreamRED[A]) extends StreamRED[A] {
  def headOption: Option[A] = Some(h())
  def toList: List[A] = h() +: t().toList
}

object StreamRED {
  def cons[A](hd: => A, tl: => StreamRED[A]): StreamRED[A] = {
    lazy val head = hd
    lazy val tail = tl
    Cons(() => head, () => tail)
  }
  def empty[A]: StreamRED[A] = Empty

  def apply[A](as: A*): StreamRED[A] =
    if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...