【问题标题】:Shapeless HList Types Extending a Common Trait扩展共同特征的无形 HList 类型
【发布时间】:2014-02-24 18:14:50
【问题描述】:

我有一些基于无形 HList 的类型:

type t1 = Int :: String :: Int :: HNil
type t2 = String :: String :: Int :: HNil

我想定义一个密封的特征ST,它是所有它们的超类型,这样,如果我有以下功能:

def fun(x:ST) = …

以下是有效的:

fun(5 :: "foo" :: 3 :: HNil)       // It is a t1
fun("foo" :: "bar" :: 42 :: HNil)  // It is a t2

但以下内容无法编译:

fun(5 :: 3 :: HNil)

如何将t1t2 定义为ST 的子类型?

更新

我认为 Coproducts 可能是一个解决方案

type ST = t1 :+: t2 :+: CNil

fun(Coproduct[ST](5 :: "foo" :: 3 :: HNil)) // compiles
fun(Coproduct[ST](5 :: 3 :: HNil))          // does not compile

【问题讨论】:

    标签: scala shapeless


    【解决方案1】:

    不可能使用别名将类型“制作”为任何事物的子类型,别名只是一个新名称。虽然您可以使用副产品,但创建一个新的类型类可能更自然:

    import shapeless._
    
    type t1 = Int :: String :: Int :: HNil
    type t2 = String :: String :: Int :: HNil
    
    trait Funnable[A]
    
    implicit object t1Funnable extends Funnable[t1]
    implicit object t2Funnable extends Funnable[t2]
    
    def fun[A: Funnable](x: A) = x
    

    现在你要编译的行会,你不想编译的行不会。

    【讨论】:

    • 谢谢!我将其修改为:def fun[A <: HList](x:A)(implicit funnable:Funnable[A]) = x 以保留 x 的一些类型信息
    • 太棒了!请注意,您还可以在类型类本身的类型参数上添加 HList 约束(根据您使用它的方式,这可能有意义也可能没有意义)。
    • 实际上,这是我尝试的第一件事,但是编译器(Scala 2.10.??)无法推断出函数参数 x 是 HList 。最后,我保留了这两个约束。
    • 抱歉,我没说清楚,但是是的,这就是我的意思——你可以在两个地方都设置约束。
    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2016-09-13
    • 2014-06-03
    • 2021-02-18
    • 1970-01-01
    • 2017-02-10
    • 2016-11-28
    • 1970-01-01
    相关资源
    最近更新 更多