I see two possible solutions:
Unboxed Type Tags. . , , .
- :
type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
trait Positive
trait One2Three
type PositiveInt = Int @@ Positive
type SmallInt = Int @@ One2Three
//Builds a small int
def small(i: Int): SmallInt = {
require( i > 0 && i < 4, "should be between 1 and 3" )
i.asInstanceOf[SmallInt]
}
//Builds a positive int
def positive( i: Int): PositiveInt = {
require( i >= 0, "should be positive" )
i.asInstanceOf[PositiveInt]
}
//Example usage in methods
def mul( i: SmallInt, j: PositiveInt ): PositiveInt = positive(i*j)
REPL:
scala> mul( small(2), positive(4) )
res1: PositiveInt = 8
scala> mul( small(4), positive(2) )
java.lang.IllegalArgumentException: should be between 1 and 3
scala> mul( 2, positive(2) )
<console>:16: error: type mismatch;
found : Int(2)
required: SmallInt
mul( 2, positive(2) )
^
, Scala 2.10. SIP-15, , .