【问题标题】:Shapeless: Trying to restrict HList elements by their typeShapeless:试图通过类型来限制 HList 元素
【发布时间】:2015-09-26 06:17:52
【问题描述】:

问题 1 - 基本 LUB 约束

我第一次尝试使用现有的 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

【问题讨论】:

  • 我设法通过在本地声明 implicit val hnilLUBForLong = new LUBConstraint[HNil.type, Long] {} 来绕过第一个错误(在 问题 1 的代码块中) - 声明的方法提供的隐式值似乎没有'类型不完全匹配:LUBConstraint[HNil, Long] =!= LUBConstraint[HNil.type, Long] 意图甚至是错误?
  • 处理 CPConstraint 的隐式解析(参见 问题 2)拥有 val 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] {},它NOT 是否适合隐式搜索,但 implicit val scpcEmptyLong2: CPConstraint[hlLong.type, CPType] = new CPConstraint[hlLong.type, CPType] {} 会。 - 为什么???有什么区别?
  • 这应该是三个独立的问题。在第一种情况下,您可以通过将 HNil 显式键入为 HNil 来解决问题:acceptLong(HNil: HNil) 应该可以编译。
  • 好的 - 我会尝试拆分问题。
  • @TravisBrown - 谢谢,明确输入帮助。

标签: scala constraints shapeless hlist


【解决方案1】:

HNil 的推断类型将是单例类型HNil.type,它是HNil 的正确子类型。因为像LUBConstraint 这样的类型类是不变的,所以如果您请求HNil.type 的实例,将找不到任何HNil 的可用实例。

some discussion 已经更改了 HNil 的定义,以便这样做,但这并不是微不足道的,而且不清楚更改的所有含义是否都是可取的。同时您可以写HNil: HNil 来向上转换值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多