将隐式解析与类型 lambda 混合
Mixing Implicit resolution with type lambdas
我知道这道题是深度类型编程,我的失败是因为缺乏知识。但我至少想知道如何编译这个。我需要编译器确定我的 tuple2 在上下文中可以是 Higher-Kinded 类型。
trait Extract[T[_],A]{
def extract(t: T[A]): A
}
object Extract{
type T2[B] = {type l[X] = (X,B)}
implicit def forTuple2[A,B] = new Extract[T2[B]#l,A] {
override def extract(t: (A, B)): A = t._1
}
}
def method[T[_],A](a: T[A])(implicit extractor: Extract[T,A]): A = extractor.extract(a)
method[Extract.T2[String]#l,Int]((1,"hi")) //this works but is useless.
//the whole point is to get the compiler to do the heavy lifting And in
//this case it means inferring that a tuple2 of (X,whatever) is a T[X] for the context
任何尽可能接近我的目标的东西都会受到赞赏。我也知道 shapeless 有一个专门用于这些东西的库。但让我们假设不存在 shapeless 来解决我的问题。
编译器无法知道你想要type T[X] = Tuple2[X, A]
还是T[X] = Tuple2[X, A]
,所以它甚至在查看隐式参数之前就放弃了。你在隐含的正确轨道上,除了在这种情况下你甚至不需要通过类型 lambda(你不会将 Tuple2[_, A]
视为 T[A]
):
def method[X, A](x: X)(implicit ev: Open[X, A]): A =
ev.open(x)
Open
指定要使用 Tuple2
的哪个洞:
trait Open[X, Out] {
def open(x: X): Out
}
object Open {
implicit def firsthole[A, B] = new Open[Tuple2[A, B], A] {
def open(x: Tuple2[A, B]) = x._1
}
}
I know this question is deep type level programming
深?你还没有看到什么(͡°͜ʖ͡°)
我知道这道题是深度类型编程,我的失败是因为缺乏知识。但我至少想知道如何编译这个。我需要编译器确定我的 tuple2 在上下文中可以是 Higher-Kinded 类型。
trait Extract[T[_],A]{
def extract(t: T[A]): A
}
object Extract{
type T2[B] = {type l[X] = (X,B)}
implicit def forTuple2[A,B] = new Extract[T2[B]#l,A] {
override def extract(t: (A, B)): A = t._1
}
}
def method[T[_],A](a: T[A])(implicit extractor: Extract[T,A]): A = extractor.extract(a)
method[Extract.T2[String]#l,Int]((1,"hi")) //this works but is useless.
//the whole point is to get the compiler to do the heavy lifting And in
//this case it means inferring that a tuple2 of (X,whatever) is a T[X] for the context
任何尽可能接近我的目标的东西都会受到赞赏。我也知道 shapeless 有一个专门用于这些东西的库。但让我们假设不存在 shapeless 来解决我的问题。
编译器无法知道你想要type T[X] = Tuple2[X, A]
还是T[X] = Tuple2[X, A]
,所以它甚至在查看隐式参数之前就放弃了。你在隐含的正确轨道上,除了在这种情况下你甚至不需要通过类型 lambda(你不会将 Tuple2[_, A]
视为 T[A]
):
def method[X, A](x: X)(implicit ev: Open[X, A]): A =
ev.open(x)
Open
指定要使用 Tuple2
的哪个洞:
trait Open[X, Out] {
def open(x: X): Out
}
object Open {
implicit def firsthole[A, B] = new Open[Tuple2[A, B], A] {
def open(x: Tuple2[A, B]) = x._1
}
}
I know this question is deep type level programming
深?你还没有看到什么(͡°͜ʖ͡°)