问题1 - 基本的LUBConstraints
我尝试使用现有的LUBConstraints进行操作时遇到了缺少证据的失败情况(请参阅以下代码块)。是否可以给出任何提示?空列表不是一个有效的长整型列表吗?没有元素违反了约束条件。
import shapeless.ops.coproduct
import shapeless.{::, :+:, Coproduct, HNil, HList}
object testLUBConstraints {
import shapeless.LUBConstraint._
// !!! see comment on question - this satisfies the implicit below!!!
// implicit val hnilLUBForLong = new LUBConstraint[HNil.type, Long] {}
def acceptLong[L <: HList : <<:[Long]#λ](l: L) = true
val validLong = acceptLong(1l :: HNil)
val validEmpty = acceptLong(HNil)
// => WHY??? Error: could not find implicit value for evidence parameter of type shapeless.LUBConstraint[shapeless.HNil.type,Long]
// MY EXPECTATION WAS: 'implicit def hnilLUB[T] = new LUBConstraint[HNil, T] {}' defined within LUBConstraint companion should provide so
// val invalid = acceptLong(1.0d :: HNil) -> fails due to missing evidence (as expected)
}
非常感谢您的支持。
问题2 - 使用Coproduct拥有自己的约束条件 (分为一个单独的问题:Shapeless:使用Coproduct拥有自己的HList约束条件)
问题3 - 通过参数类型限制case classes (分为一个单独的问题:Shapeless:限制case class类型)
implicit val hnilLUBForLong = new LUBConstraint[HNil.type, Long] {}
来解决第一个错误。似乎声明的方法提供的隐式值并不完全匹配类型:LUBConstraint[HNil, Long] =!= LUBConstraint[HNil.type, Long]
。这是意图还是一个错误? - sthieloval hlLong: ::[Long, HNil] = 1L :: HNil
,并且通过implicit val cpcLong = implicitly[CPConstraint[hlLong.type, CPType]]
隐式查找CPConstraint。我尝试了implicit val scpcEmptyLong1: CPConstraint[::[Long,HNil], CPType] = new CPConstraint[::[Long,HNil], CPType] {}
,但它不符合隐式搜索,而implicit val scpcEmptyLong2: CPConstraint[hlLong.type, CPType] = new CPConstraint[hlLong.type, CPType] {}
则符合。-为什么?有什么区别? - sthieloHNil
显式地类型化为HNil
来解决问题:acceptLong(HNil: HNil)
应该编译。 - Travis Brownimplicit def hnilLUB[HN <: HNil, T] = new LUBConstraint[HN, T] {}
- 这是否值得提出改进建议? - sthielo