无形:尝试按类型限制HList元素

时间:2015-09-25 09:13:49

标签: scala constraints shapeless hlist

问题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: own HList constraint using Coproduct

问题3 - 按参数类型限制案例类 (分成一个单独的问题:Shapeless: restricting case class types

1 个答案:

答案 0 :(得分:4)

HNil的推断类型将是单例类型HNil.type,它是HNil的正确子类型。由于LUBConstraint等类型类是不变的,因此如果您要求HNil的实例,则无法找到HNil.type的任何可用实例。

已经some discussion改变了HNil的定义,以便这样做有效,但这不是微不足道的,而且并不清楚所有的改变的含义是可取​​的。在此期间,您可以编写HNil: HNil来更新价值。