首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从序列创建受约束的HList?

如何从序列创建受约束的HList?
EN

Stack Overflow用户
提问于 2017-05-18 07:04:58
回答 1查看 192关注 0票数 3

我有一个具有以下签名的构造函数:

代码语言:javascript
运行
复制
class Event[DL <: HList](
  detailsIn: DL
)(implicit lbcr: LUBConstraint[DL, EventDetail[_]]) { ... 

在我的同伴对象中,我有:

代码语言:javascript
运行
复制
  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方法是可以清理的。

这产生了以下错误,坦率地说,我不知道如何处理:

代码语言:javascript
运行
复制
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。

EN

回答 1

Stack Overflow用户

发布于 2017-05-18 15:13:21

不要害怕类型错误,它非常明确,让我尝试自下而上键入您的apply方法体:

在最下面有一个String :: HNil

代码语言:javascript
运行
复制
val e0: String :: HNil = e.toList.toHList[String :: HNil].get

if不会改变这一点:

代码语言:javascript
运行
复制
val e1: String :: HNil = 
  if (???) e0
  else throw new NotImplementedException()

因此,当您创建Event时,Event.DL = String :: HNil

代码语言:javascript
运行
复制
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]

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44036089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档