【发布时间】:2018-05-05 10:50:09
【问题描述】:
我正在研究一个链接隐式函数的系统,它类似于下面的简化示例。测试c1.payload == c2.payload 代表我需要做的不在“类型空间”中的测试;我曾期望我会放入一个宏来定义witnessEvidence,但是 Scala 显然不允许使用任意类型的隐式参数(仅限 WeakTypeTag 值!)的宏定义,所以我对如何继续感到有些困惑有了这个。下面的代码在逻辑上显示了我想要发生的事情,但是隐式函数不能有条件地产生或不产生证据(除非它在宏实现中)。
case class Capsule[T](payload: Int)
trait A
trait B
trait C
implicit val capa = Capsule[A](3)
implicit val capb = Capsule[B](3)
implicit val capc = Capsule[C](7)
case class Evidence[T1, T2](e: Int)
implicit def witnessEvidence[T1, T2](implicit c1: Capsule[T1], c2: Capsule[T2]): Evidence[T1, T2] = {
if (c1.payload == c2.payload)
Evidence[T1, T2](c1.payload)
else
// Do not produce the evidence
}
def foo[T1, T2](implicit ev: Evidence[T1, T2]) = ev.e
val f1 = foo[A, B] // this should compile
val f2 = foo[A, C] // this should fail with missing implicit!
【问题讨论】:
-
在编译时是否知道
Capsule值,尤其是它们的payload字段? -
payload值是作为链式隐式解析的副产品生成的(这部分似乎工作正常)。所以它在编译时可用。但是信息不是以类型的形式编码的。我正在研究一种替代方法,将信息编码为 HList 记录,以便隐式解析可以代替它。
标签: scala macros scala-macros implicits