Scala: что-то вроде Option (Some, None), но с тремя состояниями: Some, None, Unknown
мне нужно вернуть значения, и когда кто-то просит значение, скажите им одну из трех вещей:
- здесь значение
- не имеет значения
- у нас нет информации об этом значении (неизвестно)
случай 2 тонко отличается от случая 3. Пример:
val radio = car.radioType
- мы знаем значение: возвратите тип радио, скажите "Пионер"
- b. нет значения: return None
- Си. нам не хватает данные об этом автомобиле, мы не знаем, есть ли у него радио или нет
Я думал, что могу расширить Scala None и создать неизвестное, но это кажется невозможным.
предложения?
спасибо!
обновление:
в идеале я хотел бы написать примерно такой код:
car.radioType match {
case Unknown =>
case None =>
case Some(radioType : RadioType) =>
}
6 ответов
вот реализация barebones. Вероятно, вы хотите посмотреть источник для класса Option для некоторых колоколов и свистков:
package example
object App extends Application {
val x: TriOption[String] = TriUnknown
x match {
case TriSome(s) => println("found: " + s)
case TriNone => println("none")
case TriUnknown => println("unknown")
}
}
sealed abstract class TriOption[+A]
final case class TriSome[+A](x: A) extends TriOption[A]
final case object TriNone extends TriOption[Nothing]
final case object TriUnknown extends TriOption[Nothing]
никому не говорите, что я предложил это, но вы всегда можете использовать null для неизвестного, а не писать новый класс.
car.radioType match {
case null =>
case None =>
case Some(radioType : RadioType) =>
}
вы можете захватить некоторые вещи из лифта: коробка. Она имеет три состояния: полное, несостоятельное и пустое. Кроме того, Empty и Failure наследуются от EmptyBox.
вы можете использовать scala.Любой. Используйте Left для исключительного значения и Right для ожидаемого значения, которое может быть опцией в этом случае:
scala> type Result = Either[String, Option[String]]
defined type alias Result
scala> val hasValue: Result = Right(Some("pioneer"))
hasValue: Result = Right(Some(pioneer))
scala> val noValue: Result = Right(None)
noValue: Result = Right(None)
scala> val unknownValue = Left("unknown")
unknownValue: Left[java.lang.String,Nothing] = Left(unknown)
вы можете создать свой собственный с трех возможностей. Или как одна из ваших машин.типы радиотипов, которые вы могли бы неизвестны, а затем использовать охранников в вашем случае, чтобы справиться с этим. Если вы катите свой собственный, вы также должны включить характеристику продукта. liftweb имеет тип коробки, который является опцией закрыть, что позволяет полный, пустой и erorr произойти.
Я сделал что-то похожее на классификацию 3 типов строк в данном файле, возможно, заданная строка, например,Float
в строке заголовка Long
для строки в середине (строка) или String
для линии прицепа. Также isHeader
, isRow
и isTrailer
можно использовать, чтобы узнать, какой из них. Надеюсь поможет:
sealed abstract class HRT[+H, +R, +T] {
val isHeader: Boolean
val isRow: Boolean
val isTrailer: Boolean
}
final case class Header[+H, +R, +T](h: H) extends HRT[H, R, T] {
override val isHeader: Boolean = true
override val isRow: Boolean = false
override val isTrailer: Boolean = false
}
final case class Row[+H, +R, +T](r: R) extends HRT[H, R, T] {
override val isHeader: Boolean = false
override val isRow: Boolean = true
override val isTrailer: Boolean = false
}
final case class Trailer[+H, +R, +T](t: T) extends HRT[H, R, T] {
override val isHeader: Boolean = false
override val isRow: Boolean = false
override val isTrailer: Boolean = true
}
object Demo {
def getEntries(): Seq[HRT[Float, Long, String]] =
List(
Header(3.14f),
Row(42),
Trailer("good bye")
)
val entries = getEntries()
entries.foreach {
case Header(f) => printf("header: %f\n", f)
case Row(l) => printf("row: %d\n", l)
case Trailer(s) => printf("trailer: %s\n", s)
}
}