私が達成しようとしているのは、次の方法です。
- 異種リストのタイプのリストを定義する
- 上記の定義から、静的に型指定された値のリストを作成します
理想的には、IDE で次の式を入力したいと思います。
val record = types.addValue("test").addValue(123).addValue(new java.util.Date())
addValue()IDE 型推論エンジンによって制約される引数の型を持つ。
以下は、ポイント 1の実用的な実装です: レコード フィールド タイプの仕様:
case class FieldType[V, T <: FieldType[_, _]](clazz: Class[V], tail: T) {
def addValue(value: V) = FieldValue(value, tail)
}
case class FieldValue[V, T <: FieldType[_, _]](value: V, tail: T)
object emptyFieldType extends FieldType(classOf[Null], null)
これは、以下で構成されるレコードの仕様の例ですString, Int, Date。
val types = FieldType(
classOf[String], FieldType(
classOf[Int], FieldType(
classOf[java.util.Date], emptyFieldType
)
)
)
addValue型でメソッドを使用することによりFieldType、コンパイラは任意の深さで引数の型を認識します。
val a = types.addValue("") // here only String allowed
val b = types.tail.addValue(23) // here only Int allowed
val c = types.tail.tail.addValue(new java.util.Date()) // here only Date allowed
しかし....
FieldValue最初の例のように流暢なインターフェイスを実現するために、型に転送メソッドを実装する方法をまだ見つけていません。
val record = types.addValue("test").addValue(123).addValue(new java.util.Date())
これは、アイデアを与えるための擬似コードです。
case class FieldValue[V, T <: FieldType[_, _]](value: V, tail: T) {
def addValue(x: What Here??) = tail.addValue(x) // not compiling!
}
の次の引数の型情報は、メンバー経由で asaddValueに含まれているため、可能であるに違いないと思います。しかし、この情報をメソッドで利用できるようにし、コンパイラが引数値の型を検証し、IDE が正しい型を提案できるようにする方法を見つけることができませんでした。FieldValuetailVaddValue