无形:前置。隐含未找到

时间:2012-06-14 15:23:34

标签: scala functional-programming shapeless

我正在尝试使用无形的方式以类型安全的方式轻松累积对象。

问题在于我想要连结两个::: HList}。我遇到了一个新手(似乎至少)问题。它错过了上下文中的Prepend隐式实例。

但是,在查看hlist.scala后,我可以看到对象implicit defPrepend中定义了通用PrependAux

手动添加import Prependimport PrependAux并未改变任何内容(显然......)。

所以这里代码减少到最低限度:

enter code here

import shapeless._
import HList._
import Prepend._
import PrependAux._

object test {

  val a:HList = 1 :: 4 :: "A" :: HNil
  val b:HList = "R" :: false :: HNil

  val c:HList = a ::: b   // <<<<<<<<<<< NEEDS A Prepend in the context 

}

现在在控制台中:

[error]     test.scala:10: could not find implicit value for parameter prepend: shapeless.Prepend[shapeless.HList,shapeless.HList]
[error]     val c:HList = a ::: b   // this needs an implicit Prepend in the current context

什么应该烧我的眼睛?

感谢

修改

稍微更新一点,重新解决一些真正的问题,因为之前的庸俗化是强大的。

以下是我能做的事情:

case class A[L<:HList](a:L) { 
  def doSmth[C <:HList](c:C) = a ::: c 
}

所以我没有访问真实类型,只知道他们是 HList

1 个答案:

答案 0 :(得分:10)

HList的向上转换是这里的问题。普通的HList几乎没有什么可以做的(除了向它添加新元素)。

您可以提供更具信息性的类型注释:

val a: Int :: Int :: String :: HNil = 1 :: 4 :: "A" :: HNil
val b: String :: Boolean :: HNil = "R" :: false :: HNil
val c: Int :: Int :: String :: String :: Boolean :: HNil = a ::: b

或者只是推断出类型,这通常更方便:

val a = 1 :: 4 :: "A" :: HNil
val b = "R" :: false :: HNil
val c = a ::: b

回应你的评论:如果你确定你已经得到了你需要的证据,你可以做你想做的事(请注意,我认为a: Aa: L的拼写错误,并且你需要-Ydependent-method-types来实现这一点):

case class A[L <: HList](a: L) {
  def doSmth[C <: HList](c: C)(implicit p: Prepend[L, C]) = a ::: c
}

一般情况下,您只需查看您正在使用的操作所必需的含义,然后将其包含在您的方法中。