как выставить тест на совпадение с шаблоном - PullRequest
3 голосов
/ 11 сентября 2010

Я новичок в скале, но в основном нашел свой путь ...

Здесь я прошу рекомендовать / рекомендовать / идиоматический способ реализации этого:

  • внутренне, MyClass использует тип state , который реализуется запечатанной иерархией классов дел
  • но в API должен быть представлен только некоторый логический предикат, который реализуется путем сопоставления с (внутренним) состоянием.

В настоящее время моя реализация соответствует принципам ...

def isSane: Boolean = state match {
    case Ok(_,'valid) => true
    case _            => false
}

Но это решение кажется мне неловким, как будто бы что-то выражается в трех строках кода, в которых содержится только информационное содержимое, стоящее одной строки кода. На самом деле я хотел бы написать:

def isSane: boolean = state matches Ok(_, 'valid)

Вероятно / вероятно, возможно реализовать подходящий оператор самостоятельно в Scala, но прежде чем я в этом разбираюсь, я хотел бы знать, каков был бы обычный способ решения этой проблемы. Может быть, есть еще какая-то существующая реализация библиотеки?

Ответы [ 3 ]

2 голосов
/ 11 сентября 2010

Возможно, я старомоден, но почему бы не использовать полиморфизм?

trait State { def sane: Boolean }

trait InvalidState extends State { def sane = false }

case class Ok(whatever: Whatever, s: Symbol) extends State {
   def sane = { s == 'valid }
}

case class Failure(msg: String) extends InvalidState 

case class WarmingUp extends InvalidState

// ...

def isSane(): Boolean = state.sane

Конечно, если по какой-то причине это невозможно, вы можете обобщить решение Даниэля несколько:

class Matcher[T](o: T) {
   def matches(pf: PartialFunction[T, Unit]) = pf isDefinedAt o
}

object Matcher {
   implicit def o2matcher[T](o: T): Matcher[T] = new Matcher(o)
}

// then
def isSane = state matches { case Ok(_,'valid) => }
2 голосов
/ 11 сентября 2010

Я бы сделал что-то вроде этого:

abstract class State {
  def matches(pf: PartialFunction[State, Unit]) = pf isDefinedAt this
}

// then

def isSane = state matches { case Ok(_,'valid) => }

Поскольку matches определено для получения частичной функции, вы можете следовать за ней с помощью литерала функции, содержащего только операторы case, которые должны приводить к true. Вам не нужно ничего возвращать, так как частичная функция определена как возвращающая Unit. Наконец, метод matches использует метод частичных функций isDefinedAt, чтобы проверить, есть ли оператор case, охватывающий себя.

1 голос
/ 11 сентября 2010

Если свойство Symbol статически известно как свойство типа state:

def isSane: Boolean =
  state.secondSymbolPropertyWhateverItsCalled == 'valid

Если вы не знаете, что state является Ok, то:

def isSane: Boolean =
  state.isInstanceOf[Ok] && state.asInstanceOf[Ok].symbolProp == 'valid

но на данный момент это не совсем то, что вы написали.

Наконец, вы можете просто определить isSane для этой иерархии типов и делегировать ей:

def isSane: Boolean =
  state.isSane
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...