我有一个具有以下签名的构造函数:
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)
诚然,这个apply方法是可以清理的。
这产生了以下错误,坦率地说,我不知道如何处理:
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。
发布于 2017-05-18 15:13:21
不要害怕类型错误,它非常明确,让我尝试自下而上键入您的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*)
的支持下,您可以将varargs作为HList
而不是Seq[String]
。
https://stackoverflow.com/questions/44036089
复制相似问题