如何使用通用约束类型

时间:2015-06-29 09:08:21

标签: scala types

我想用scala类型系统表示一些约束数据,带有常量。 例如在伪代码中,我想写的是这样的,(如果可能的话,可选择使用编译时检查约束)

val data1 : String of 10
val data2 : Int of (0..10)
val data3 : Int of (1..1000)
val data4 : String of 30

// etc.

不为每种类型编写此类代码:

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.

是否存在一些提出这种结构的图书馆? 有没有办法,有这样的通用结构? 也许使用宏,但我不确定它是个好主意,而且我不能流利。

您如何看待我应该朝哪个方向前进?

2 个答案:

答案 0 :(得分:5)

不确定这是否是您正在寻找的内容,但我在此处看到的内容会立即让我想起 refined 。那是你在找什么?

答案 1 :(得分:0)

也许您可以使用partial functions

val strOf10: PartialFunction[String, String] = { case str if (str.length == 10) => str};

val a = List("a", "abc", "abcdefghij");

scala> a collect strOf10
res5: List[String] = List(abcdefghij)