我有以下方法:
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]
的通用隐式,为什么它在其他情况下有效?
最佳答案
您将看到自动tupling的结果,这是一个Scala(错误)功能,导致lift(true, 5)
被解析为lift((true, 5))
当没有具有适当数量值(在本例中为两个)的 lift
方法时。但是,编译器不会自动将单个值包装在 Tuple1
中,您只会收到编译器错误。
例如参见 this answer有关自动调整的更多详细信息,以及 this thread由于某些原因,在您的语言中包含自动匹配是一件很糟糕的事情。
有几种可能的解决方法。第一种方法是创建从值到 Tuple1
的隐式转换,如 this answer 中建议的那样。 。我个人不会推荐这种方法——您在代码中引入的每个隐式转换都是雷区中的另一个地雷。
相反,我建议完全避免自动组合。显式地写出 list((true, 5))
— 只需几个额外的字符即可获得更多的清晰度。不幸的是,对于 Tuple1
没有类似的文字支持,所以你必须写出 lift(Tuple1("string"))
,但即使这样也不算太糟糕,如果你真的希望您可以定义一个新的 liftOne
方法来为您完成此操作。
关于scala - 将单个参数转换为具有无形泛型的 HList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22385535/