Другие ответы касаются в основном вопроса о создании типа «положительное число», которое относится к типу «число» таким образом, чтобы компилятор мог гарантировать корректность.Например, с зависимыми типами вы можете доказать, что реализация таких функций, как abs
, является правильной.Вы не можете сделать это с помощью scala.
Однако вы можете создать тип, представляющий положительные целые числа и ничего больше.Например:
abstract class Pos {
def toInt: Int
}
case object Zero extends Pos {
def toInt: Int = 0
}
case class Next(x: Pos) extends Pos {
def toInt: Int = 1 + x.toInt
}
object Pos {
def apply(x: Int): Pos =
x match {
case n if (n < 0) => throw new IllegalArgumentException(s"$x is not a positive integer")
case 0 => Zero
case n => Next(Pos(n-1))
}
}
Это похоже на то, что предложил ziggystar, с той разницей, что правильность типа гарантируется его собственной конструкцией, а не конструктором.То есть невозможно представить отрицательное число с этим типом.
Этот подход, вероятно, не будет практичным для ваших целей.Вам либо нужно реализовать все операции для него, либо добавить значение Int, которое затем эквивалентно простой проверке во время выполнения, поскольку вы теряете всю безопасность типов, которую выиграли, представляя таким образом положительные целые числа.
Топо сути, то, что произошло бы в вашем примере.Поскольку Pos.apply
не является безопасным типом, вы не можете получить ошибку компиляции в
myMethod(-5)