scala - Restrict method of a trait with constraint on abstract type member using implicits? -
i in 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] base trait , ast dsl, overload built-in scala operators in trait allow infix notation on dsl, constrain of these methods bound on type t @ trait level same operation here '&&' has different semantics depending on type t.
it seems leibniz subsitution not/cannot work here (maybe because defined functors f[_] 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 approach constraining trait's t parameter make sense @ ? there way make leibniz work in case "hiding" second parameter c :
type expf[t] = exp[t, _]
if makes sense? thanks,
exactly that; define such type , use leibniz.lift
to, well, lift 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) }
Comments
Post a Comment