Шаблон сопоставления пользовательских реализаций List ADT - PullRequest
1 голос
/ 12 февраля 2020

Я понимаю (вроде), как работает сопоставление с образцом в Scala. Допустим, у меня есть два списка в форме:

  sealed abstract class IntList
  case class Empty()                        extends IntList // The empty list, often called Nils
  case class Element(n: Int, tail: IntList) extends IntList // Element is usually called Cons

Допустим, я хочу создать функцию take(n, xs)

  • Он должен вернуть первые n элементов xs.

Я пытался с нормальным сопоставлением с образцом:

  def take(n: Int, xs: IntList): IntList = xs match {
    case n == 0 => Empty()
    case xs : Empty => Empty() 
    case xs : Element => Element(xs.n, take(n-1, xs))
  }

Но тогда, конечно, n не error: not found: value == case n == 0 => Empty()

Как я могу это сделать, возможно, это просто, но я новичок в Scala?

1 Ответ

2 голосов
/ 12 февраля 2020

У вас есть опечатка в первом случае, где она должна быть

case _ if n == 0 => Empty()

, и ошибка в третьем случае, когда вы забыли передать tail

case xs: Element => Element(xs.n, take(n-1, xs.tail))

Попробуйте

sealed trait IntList
case object Empty extends IntList
case class Element(n: Int, tail: IntList) extends IntList

def take(n: Int, xs: IntList): IntList = xs match {
  case _ if n == 0 => Empty
  case Empty => Empty
  case Element(n, tail) => Element(n, take(n-1, tail))
}

val list = Element(1, Element(2, Element(3, Empty)))
take(2, list)   // res0: IntList = Element(1,Element(2,Empty))

Рассмотрим case object вместо case class Empty(), когда нет данных согласно Различия между объектом case T и классом case T () при определении ADT?

...