Я реализовал игру! 2 QueryStringBindable в Scala для типа Range. Диапазон состоит из минимального или максимального значения или обоих (типа Float). В моей реализации QueryBindable я использую innerBinder, чтобы преобразовать два возможных параметра min и max в Option [Либо [String, Float]], объединить их в кортеж, выполнить сопоставление шаблона над этим и, наконец, вернуть параметр [Либо [String, Ассортимент]]. Это работает, но, как вы можете видеть в приведенном ниже коде, совпадение шаблонов очень много. Есть ли более лаконичный способ сделать это в Scala? Возможно ли использовать функции более высокого порядка, чтобы как-то вернуть ту же структуру результатов?Упрощение или альтернатива для этого соответствия шаблону Scala
import play.api.mvc.QueryStringBindable
case class Range(min: Option[Float], max: Option[Float])
object Range {
implicit def rangeQueryStringBindable(implicit intBinder: QueryStringBindable[Float]) = new QueryStringBindable[Range] {
override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, Range]] = {
val minOpt = intBinder.bind("min", params)
val maxOpt = intBinder.bind("max", params)
(minOpt, maxOpt) match {
case (None, None) => None
case (Some(Right(min)), Some(Right(max))) => Some(Right(Range(Some(min), Some(max))))
case (None, Some(Right(max))) => Some(Right(Range(None, Some(max))))
case (Some(Right(min)), None) => Some(Right(Range(Some(min), None)))
case (Some(Left(minError)), Some(Left(maxError))) => Some(Left(minError))
case (Some(Left(minError)), None) => Some(Left(minError))
case (None, Some(Left(maxError))) => Some(Left(maxError))
case (Some(Right(_)), Some(Left(maxError))) => Some(Left(maxError))
case (Some(Left(minError)), Some(Right(_))) => Some(Left(minError))
}
}
override def unbind(key: String, range: Range): String = {
(range.min, range.max) match {
case (Some(min), Some(max)) => intBinder.unbind("min", min) + "&" + intBinder.unbind("max", max)
case (Some(min), None) => intBinder.unbind("min", min)
case (None, Some(max)) => intBinder.unbind("max", max)
case (None, None) => throw new IllegalArgumentException("Range without values makes no sense")
}
}
}
}
Спасибо! Это выглядит намного более кратким! – user3053314