【问题标题】:Restrict method of a trait with constraint on abstract type member using implicits?使用隐式限制具有抽象类型成员约束的特征方法?
【发布时间】:2015-02-14 20:59:08
【问题描述】:

我的情况如下:

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, _]

如果这有道理? 谢谢,

【问题讨论】:

    标签: scala type-conversion scalaz implicits


    【解决方案1】:

    正是如此;定义这样一个类型,然后使用Leibniz.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)
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 2021-01-24
      • 1970-01-01
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多