我有一个具有以下签名的构造函数:
class Event[DL <: HList](
detailsIn: DL
)(implicit lbcr: LUBConstraint[DL, EventDetail[_]]) { ...
在我的伴侣对象中:
def apply[DL <: HList](
detailIn: String*
)(implicit lbcr: LUBConstraint[DL, EventDetail[String]]) =
new Event(
if (detailIn.map(deet => EventDetail(deet)).toList.size == 1)
detailIn.map(deet => EventDetail(deet)).toList.toHList[String :: HNil].get
else throw new NotImplementedException()
)(lbcr)
不可否认,这种申请方法可以清理干净。
这会产生以下错误,我坦率地说该如何处理这个错误:
Error:(87, 7) type mismatch;
found : shapeless.LUBConstraint[DL,edu.cornell.ansci.dairy.econ.model.event.EventDetail[String]]
required: shapeless.LUBConstraint[shapeless.::[String,shapeless.HNil],edu.cornell.ansci.dairy.econ.model.event.EventDetail[_]]
问题的第二部分:有没有办法使这个多态性超过detailIn的大小?根据我的其他读物,我假设没有,我认为在Scala中无法做到这一点。我能做的最好的事情是为detailIn字符串序列提供固定数量长度的便利,如果超过了,则该类的用户必须直接使用HList。
答案 0 :(得分:2)
不要被这种类型错误吓到,这很明确,让我尝试自下而上键入apply
方法的正文:
在最底部,你有一个String :: HNil
:
val e0: String :: HNil = e.toList.toHList[String :: HNil].get
if
不会改变:
val e1: String :: HNil =
if (???) e0
else throw new NotImplementedException()
因此,当您创建Event
,Event.DL = String :: HNil
:
new Event[String :: HNil](e1)(lbcr)
但lbcr
的类型为LUBConstraint[DL, _]
,与LUBConstraint[String :: HNil, _]
不兼容!
对于问题的第二部分,shapeless提供了一种比varargs更安全的替代方案:ProductArgs。以宏{object myfunction extends ProductArgs { def applyProduct[L <: HList](args: L) }
而不是def myfunction(args: Any*)
为基础,您可以使用HList
代替Seq[String]
来支持您的varargs。