我处于以下情况:
import scalaz.Leibniz._
trait Exp[T, C] {
def &&(that: Exp[T, C])(implicit evT: T === Boolean) = LogicalAnd(this, that)
def &&(that: Exp[T, C])(implicit evT: T === Int) = BitwiseAnd(this, that)
}
case class LogicalAnd[C](e1: Exp[Boolean, C], e2: Exp[Boolean, C]) extends Exp[Boolean, C]
case class LogicalOr[C](e1: Exp[Boolean, C], e2: Exp[Boolean, C]) extends Exp[Boolean, C]
...
case class BitwiseAnd[C](e1: Exp[Int, C], e2: Exp[Int, C]) extends Exp[Int, C]
case class BitwiseOr[C](e1: Exp[Int, C], e2: Exp[Int, C]) extends Exp[Int, C]
...
特征 Exp[T,C] 是 DSL 的基本特征和 AST,我想在这个特征中重载内置的 scala 运算符以允许在这个 dsl 上使用中缀符号,但是我想限制其中的一些方法在特征级别对类型 T 进行了限制,因此此处的相同操作 '&&' 具有不同的语义,具体取决于类型 T。
似乎莱布尼茨替代在这里不起作用/不能起作用(可能是因为它只为具有单个参数的函子 F[_] 定义):
[error] /home/remi/Projects/DSL/src/main/scala/Exp.scala:80: type mismatch;
[error] found : exp.Exp[T,C]
[error] required: exp.Exp[Boolean,?]
[error] = LogicalAnd(this, that)
[error] ^
这种限制特征 T 参数的方法是否有意义?有没有办法通过“隐藏”第二个参数 C 来使莱布尼茨在这种情况下工作:
type ExpF[T] = Exp[T, _]
如果这有道理吗?谢谢,