给定一个简单的参数化类型,如class LK[A]
,我可以写
// or simpler def tagLK[A: TypeTag] = typeTag[LK[A]]
def tagLK[A](implicit tA: TypeTag[A]) = typeTag[LK[A]]
tagLK[Int] == typeTag[LK[Int]] // true
现在我想为class HK[F[_], A]
写一个类似物:
def tagHK[F[_], A](implicit ???) = typeTag[HK[F, A]]
// or some other implementation?
tagHK[Option, Int] == typeTag[HK[Option, Int]]
这可能吗?我试过了
def tagHK[F[_], A](implicit tF: TypeTag[F[_]], tA: TypeTag[A]) = typeTag[HK[F, A]]
def tagHK[F[_], A](implicit tF: TypeTag[F], tA: TypeTag[A]) = typeTag[HK[F, A]]
但是由于显而易见的原因(在第一种情况下F[_]
是存在类型而不是更高级的类型,在第二种TypeTag[F]
没有编译),它们都不起作用。
我怀疑答案是"这是不可能的",但如果不是,我会非常高兴。
编辑:我们目前使用WeakTypeTag
如下(略微简化):
trait Element[A] {
val tag: WeakTypeTag[A]
// other irrelevant methods
}
// e.g.
def seqElement[A: Element]: Element[Seq[A]] = new Element[Seq[A]] {
val tag = {
implicit val tA = implicitly[Element[A]].tag
weakTypeTag[Seq[A]]
}
}
trait Container[F[_]] {
def lift[A: Element]: Element[F[A]]
// note that the bound is always satisfied, but we pass the
// tag explicitly when this is used
def tag[A: WeakTypeTag]: WeakTypeTag[F[A]]
}
val seqContainer: Container[Seq] = new Container[Seq] {
def lift[A: Element] = seqElement[A]
}
如果我们将WeakTypeTag
替换为TypeTag
,则所有这些都可以正常工作。不幸的是,这并不是:
class Free[F[_]: Container, A: Element]
def freeElement[F[_]: Container, A: Element] {
val tag = {
implicit val tA = implicitly[Element[A]].tag
// we need to get something like TypeTag[F] here
// which could be obtained from the implicit Container[F]
typeTag[Free[F, A]]
}
}
答案 0 :(得分:4)
这是否符合您的目的?
def tagHK[F[_], A](implicit tt: TypeTag[HK[F, A]]) = tt
与使用隐式参数分别获取TypeTag
和F
的{{1}}然后组合它们相反,您可以直接从编译器请求所需的标记。这会根据需要通过您的测试用例:
A
或者,如果您有tagHK[Option, Int] == typeTag[HK[Option, Int]] //true
的实例,则可以尝试:
TypeTag[A]
允许你这样做:
object HK {
def apply[F[_]] = new HKTypeProvider[F]
class HKTypeProvider[F[_]] {
def get[A](tt: TypeTag[A])(implicit hktt: TypeTag[HK[F, A]]) = hktt
}
}