【问题标题】:Type inference on contents of shapeless HList对无形 HList 内容的类型推断
【发布时间】:2014-02-20 03:50:35
【问题描述】:

这个例子被简化了。

我有一组这样的类:

case class KeyMapping[KeyType](k:KeyType)

class WrappedMapping[KeyType](m:T forSome {type T <: KeyMapping[KeyType]}) {
  val k:KeyType = ???
}

在以下代码中,类型被正确推断:

 val w = new WrappedMapping(KeyMapping("key"))

 //The statement below gives the correct error
 //type mismatch; 
 //  found : w.k.type (with underlying type String)  required: Nothing
 //val test1:Nothing = w.k

我不知道如何正确推断以下类型:

class Mappings[KeyType, L <: HList](mappings:L) {
  val k:KeyType = ???
}

val m = new Mappings(KeyMapping("key1") :: KeyMapping("key2") :: HNil)

// should not compile, k should be of type String
val test2:Nothing = m.k

有没有办法可以根据HList 的内容推断KeyType

【问题讨论】:

  • 您有什么理由不使用签名class WrappedMapping[KeyType](m: KeyMapping[KeyType])?现在,这种存在主义的类型就像拇指酸痛一样突出,这肯定会让这个问题更难回答。
  • 其实,没关系。我看到WrappedMapping 没有在Mappings 中使用
  • 您是否只想确定HList 中的所有映射都具有相同的密钥类型?目标有点不清楚。
  • 我希望Mappings 中的KeyType 被推断为键类型的上限。如果正确推理的唯一解决方案是只允许一种类型的密钥,那也很好。只要是从HList中的KeyMappings推断出来的。

标签: scala shapeless hlist


【解决方案1】:

Shapeless 提供了一个 ToList 隐式函数,毫无疑问,它用于将 HLists 转换为 Lists。

为了做到这一点,它必须首先计算 HList 中类型的 LUB(最小上限),这是你可以使用的:

import shapeless.ops.hlist.ToList

class Mappings[L <: HList, Lub](mappings:L)(implicit toList: ToList[L, Lub]) {
  ...
}

L 进入,隐式解析发现一个(也是唯一一个)有效的 ToList 实例,该实例受 L 约束,Lub 类型被拉出。

但这还不够,因为Lub 将是KeyMapping[String],而您想要的只是String 部分。像往常一样使用 shapeless,解决方案是添加另一个隐式:

class Mappings[L <: HList, Lub, KeyType](mappings:L)(
  implicit
  val toList: ToList[L, Lub],
  val kt: Lub <:< KeyMapping[KeyType]
) {
  val k: KeyType = null.asInstanceOf[KeyType]
}

(隐式不需要是vals,但如果它们是当你在 REPL 中探索事物时会有所帮助)

这断言Lub 对应于KeyMapping[KeyType] 类型(例如,它是一个子类型或完全相同的类型),其中KeyType 是未知的。同样,对于指定的约束只有一个有效的解决方案,KeyType 参数被拉出为String

我不知道你打算如何实现k,但你可能会发现拥有toList 实例有助于你这样做,因为它现在允许你调用mappings.toList

【讨论】:

  • 正如我所说,这是一个简化的示例。我不会实现k,但我确实需要正确推断KeyType(和类似的东西)。如果我能够完成图书馆,我会发布一个链接。
猜你喜欢
  • 2020-04-06
  • 2014-06-03
  • 2021-02-18
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
相关资源
最近更新 更多