简体   繁体   中英

Restrict method of a trait with constraint on abstract type member using implicits?

I am in the situation below:

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]
...

The trait Exp[T,C] is the base trait for and AST for a DSL, I would like to overload built-in scala operators in this trait to allow for infix notation over this dsl, however I would like to constrain some of these methods with a bound on the type T at the trait level so that the same operation here '&&' has a different semantics depending on the type T.

It seems that the leibniz subsitution does not/cannot work here (maybe because it is only defined for functors F[_] with a single argument):

[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]         ^

Does this approach to constraining the trait's T parameter make sense at all ? Is there a way to make leibniz work in this case by "hiding" the second parameter C with something like :

type ExpF[T] = Exp[T, _]

if that even makes sense? Thanks,

Exactly that; define such a type and then use Leibniz.lift to, well, lift your Leibniz :

def &&(that: Exp[T, C])(implicit evT: T === Boolean) = {
  type ExpF[A] = Exp[A, C]
  val ev2: (Exp[T, C] === Exp[Boolean, C]) =
    Leibniz.lift[⊥, ⊥, ⊤, ⊤, ExpF, T, Boolean](evT)
  LogicalAnd(this, that)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM