2

私が達成しようとしているのは、次の方法です。

  1. 異種リストのタイプのリストを定義する
  2. 上記の定義から、静的に型指定された値のリストを作成します

理想的には、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

4

1 に答える 1

5

shapelessをご覧になることをお勧めします。

異種リストのタイプを静的に指定する方法を示す簡単な例を次に示します。

type R = String :: Int :: java.util.Date :: HNil

val record: R = "test" :: 123 :: new java.util.Date() :: HNil
// record: R = test :: 123 :: Thu Aug 14 00:21:52 CEST 2014 :: HNil

val record: R = "test" :: "foo" :: new java.util.Date() :: HNil
// error: type mismatch;
found   : shapeless.::[String,shapeless.::[String,shapeless.::[java.util.Date,shapeless.HNil]]]
required: R
  (which expands to)  shapeless.::[String,shapeless.::[Int,shapeless.::[java.util.Date,shapeless.HNil]]]
     val record: R = "test" :: "hola" :: new java.util.Date() :: HNil
                          ^

これがすでにあなたのニーズに合っているかどうかはわかりませんが、いずれにしても、この種の汎用プログラミングに多くの機能を提供するため、shapeless のすべての機能を確認する必要があります。

于 2014-08-13T22:28:57.153 に答える