【发布时间】:2014-10-07 10:07:41
【问题描述】:
我想要实现的是一种方法:
- 为异构列表定义类型列表
- 根据上面的定义,构建一个静态类型的值列表
理想情况下,我想在 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
)
)
)
通过在FieldType 类型中使用addValue 方法,编译器可以识别任意深度的参数类型:
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!
}
我认为这一定是可能的,因为addValue 的下一个参数的类型信息通过tail 成员包含在FieldValue 中,如V。但我无法找到一种方法让 addValue 方法可以使用这些信息,让编译器验证参数值的类型,并让 IDE 建议正确的类型。
【问题讨论】:
-
你应该看看shapeless:github.com/milessabin/shapeless/wiki/…
标签: scala types type-inference type-parameter heterogeneous