Я предоставил значения по умолчанию для параметра «currentStack» в объекте «Пустой», а также в классе «Верх», но если я опускаю параметр при вызове метода push, я получаю следующее сообщение
"error: not enough arguments for method push: (newTop
: A, currentStack: Main.Stack[A])Main.Stack[A].
Unspecified value parameter currentStack.
currentBracket == '{') isBracketingValid(rest, bracketStack.push(currentBracket))".
Я попытался создать пустой стек так же, как уже заполненный, и вызвал метод push для них, который работал для добавления одного элемента.Как только я попытался добавить еще один элемент с помощью следующего push-вызова, я получил сообщение об ошибке выше.
lazy val s1 = Empty
println(s1.push(1)) // <- works
//println(s1.push(1).push(2)) <- doesn't work
lazy val s2 = Top(3, Top(4, Empty))
println(s2.push(1)) // <- works
//println(s2.push(1).push(2)) <- doesn't work
здесь определение стека:
sealed trait Stack[+A] {
def push[A] (newTop: A, currentStack: Stack[A]): Stack[A] = ???
def pop: (Option[A], Stack[A]) = ???
}
case object Empty extends Stack[Nothing] {
override def push[A] (newTop: A, currentStack: Stack[A] = Empty): Stack[A] = Top(newTop, currentStack)
override def pop: (Option[Nothing], Stack[Nothing]) = (None, Empty)
}
case class Top[A](val top: A, val rest: Stack[A]) extends Stack[A] {
override def push[A] (newTop: A, currentStack: Stack[A] = Top(top, rest)): Stack[A] = Top(newTop, currentStack)
override def pop: (Option[A], Stack[A]) = (Some(top), rest)
}
def isBracketingValid(bracketString: String): Boolean = {
def isBracketingValid(bracketList: List[Char], bracketStack: Stack[Char]): Boolean = bracketList match {
case Nil => bracketStack == Empty
case currentBracket :: rest => {
lazy val previousBracket = bracketStack.pop._1.getOrElse('$')
lazy val isRestValid = isBracketingValid(rest, bracketStack.pop._2)
if (currentBracket == '(' ||
currentBracket == '[' ||
currentBracket == '{') isBracketingValid(rest, bracketStack.push(currentBracket))
else if (currentBracket == ')') previousBracket == '(' && isRestValid
else if (currentBracket == ']') previousBracket == '[' && isRestValid
else if (currentBracket == '}') previousBracket == '{' && isRestValid
else false
}
}
isBracketingValid(bracketString.toList, Empty)
}
EDIT
переписать определение стека после намека Луиса на использование «this», так что нет, это не вызывает упомянутой проблемы, так как стек не передается, но я все еще заинтересован в понимании причины.
sealed trait Stack[+A] {
def push[A] (newTop: A): Top[A] = ???
def pop: (Option[A], Stack[A]) = ???
}
case object Empty extends Stack[Nothing] {
override def push[A] (newTop: A): Top[A] = Top(newTop, this)
override def pop: (Option[Nothing], Stack[Nothing]) = (None, Empty)
}
case class Top[A](val top: A, val rest: Stack[A]) extends Stack[A] {
override def push[A] (newTop: A): Top[A] = Top(newTop, this.asInstanceOf[Stack[A]])
override def pop: (Option[A], Stack[A]) = (Some(top), rest)
}
EDIT 2
реорганизовал определение стека благодаря пониманию Луиса, что он не использует asInstanceof, но вместо этого достигает цели с более низкой границей типа.А также проверил, почему предложения в общем случае должны быть окончательными.
sealed trait Stack[+A] {
def push[B >: A] (newTop: B): Top[B] = ???
def pop: (Option[A], Stack[A]) = ???
}
case object Empty extends Stack[Nothing] {
override def push[A] (newTop: A): Top[A] = Top(newTop, this)
override def pop: (Option[Nothing], Stack[Nothing]) = (None, Empty)
}
final case class Top[+A] (val top: A, val rest: Stack[A]) extends Stack[A] {
override def push[B >: A] (newTop: B): Top[B] = Top(newTop, this)
override def pop: (Option[A], Stack[A]) = (Some(top), rest)
}