将单个参数转换为具有无形Generic的HList

时间:2014-03-13 16:52:40

标签: scala shapeless

我有以下方法:

def lift[P <: Product, L <: HList](params: P)(implicit hl: Generic.Aux[P, L]) = {
  directive[L](_(hl to params))
}

如果我传递两个以上的参数,它就完美无缺:

val result  = lift("string", 'a', 10) // compiles
val result2 = list(true, 5) // compiles

但是,当我传递一个论点时,它无法解决隐含的问题:

val failes = lift("string") 

它无法找到[String, Nothing]隐含的Generic,为什么它在其他情况下有用?

1 个答案:

答案 0 :(得分:2)

您正在查看自动翻译的结果,这是一种Scala(错误)功能,导致lift(true, 5)在没有{{{{}}时被解析为lift((true, 5)) 1}}具有适当数量值的方法(在本例中为两个)。编译器不会自动将单个值包装在lift中,但是您只会遇到编译器错误。

请参阅示例this answer以获取有关自动翻译的更多详细信息,this thread出于某些原因,自动翻译是一种非常糟糕的事情,包含在您的语言中。

有几种可能的解决方法。第一种是根据this answer中的建议创建从值到Tuple1的隐式转换。我不会亲自推荐这种方法 - 你在代码中引入的每个隐式转换都是雷区的另一个雷。

相反,我建议完全避免自动组合。明确地写出Tuple1 - 你只需花费几个额外的字符就可以获得更多的清晰度。不幸的是,list((true, 5))没有类似的字面支持,所以你必须写出Tuple1,但即使这样也不错,如果你真的想要你可以定义一个新的lift(Tuple1("string"))方法可以为您完成。