2015-06-29 235 views
1

我想用scala類型系統和常量來表示一些受限數據。 例如,在僞代碼,我想這樣寫是這樣的,(和optionaly如果可能的話,使用編譯時檢查的約束上)如何使用泛型約束類型

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. 

是否有alrealdy存在一些圖書館這樣的建設? 有沒有辦法,有這樣的通用構造? 也許使用宏,但我不確定這是一個好主意,而且我也不流利。

你覺得我應該往哪個方向走?

回答

5

不完全確定這是你在找什麼,但我在這裏看到的瞬間讓我想起了refined。那是你在找什麼?

+0

是的,它看起來像我想要的。謝謝你的指針 – volia17

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)