I would like to represent some constrained data with scala type system, with constants. For example in pseudo code, what i would like to write is something like this, (and optionaly if possible, using compile-time checking the contraints)
val data1 : String of 10
val data2 : Int of (0..10)
val data3 : Int of (1..1000)
val data4 : String of 30
// etc.
without writing such code for every type :
type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
object Tag {
@inline def apply[T, U](t: T): T @@ U = t.asInstanceOf[T @@ U]
}
sealed trait StringOf32
object StringOf32 {
def apply(value : String) : String @@ StringOf32 = {
require(value.length <= 32)
Tag(value)
}
def unapply(s : String @@ StringOf32) : Option[String] = Some(s)
}
sealed trait IntFrom0To10
object IntFrom0To10 {
def apply(value : Int) : Int @@ IntFrom0To10 = {
require(value >= 0 && value <= 10 )
Tag(value)
}
def unapply(s : Int @@ IntFrom0To10) : Option[Int] = Some(s)
}
// etc.
Is there alrealdy exists some library wich propose this kind of construction ? Is there a way, to have such generic construction ? Perhaps using macros, but i'm not sure it's a good idea, and i'm not fluent with.
What do you think, in what direction should i go ?
Not exactly sure if this is what you are looking for but what I see here instantly reminds me of refined. Is that what you are looking for?
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments