Предоставлено простой параметризованная типа как class LK[A]
, я могу написатьПостроение TypeTags высших kinded типов
// 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[_]
экзистенциальный тип вместо высшего kinded один, во втором TypeTag[F]
не компилируется).
Я подозреваю, что ответ «это невозможно», но был бы очень рад, если это не так.
EDIT: в настоящее время мы используем WeakTypeTag
S следующим образом (несколько упрощенно):
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]]
}
}
Поможет ли это? http://stackoverflow.com/a/17791973/1223622 –
@BenReich Да, это так. Спасибо! –