首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非形状HList内容的类型推断

非形状HList内容的类型推断
EN

Stack Overflow用户
提问于 2014-02-17 10:41:57
回答 1查看 598关注 0票数 4

这个例子被简化了。

我有一套这样的课程:

代码语言:javascript
复制
case class KeyMapping[KeyType](k:KeyType)

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

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

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

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

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

有什么方法可以根据KeyType的内容推断出HList

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-19 15:27:06

无形提供了一个ToList隐式,该隐式用于将HLists转换为列表,这是不足为奇的。

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

代码语言:javascript
复制
import shapeless.ops.hlist.ToList

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

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

不过,这还不够,因为Lub将是KeyMapping[String],而您所需要的只是String部分。与往常一样,对于无形,解决方案是添加另一个隐式:

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

(不需要使用val,但是当您在REPL中探索事物时,它们会有所帮助。)

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

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

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

https://stackoverflow.com/questions/21826845

复制
相关文章

相似问题

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