Scala 静态类型异构列表生成器

Scala 静态类型异构列表生成器,scala,types,type-inference,type-parameter,heterogeneous,Scala,Types,Type Inference,Type Parameter,Heterogeneous,我努力实现的目标是: 定义异构列表的类型列表 根据上面的定义,构建一个静态类型的值列表 理想情况下,我希望在IDE中键入以下表达式: val record = types.addValue("test").addValue(123).addValue(new java.util.Date()) 具有受IDE类型推理引擎约束的addValue()的参数类型 以下是第1点的工作实现:记录字段类型规范: case class FieldType[V, T <: FieldType[_, _]]

我努力实现的目标是:

  • 定义异构列表的类型列表
  • 根据上面的定义,构建一个静态类型的值列表
  • 理想情况下,我希望在IDE中键入以下表达式:

    val record = types.addValue("test").addValue(123).addValue(new java.util.Date())
    
    具有受IDE类型推理引擎约束的
    addValue()
    的参数类型

    以下是第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)
    
    通过使用
    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!
    }
    

    case class FieldValue[V,T您可能需要查看一下

    下面是一个简单的示例,演示如何静态指定异构列表的类型:

    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
                              ^
    

    我不知道这是否已经满足了您的需求,但无论如何,您都应该检查Shapess的所有功能,因为它为此类通用编程提供了许多便利

    您应该看看Shapess:
    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
                              ^