【问题标题】:Implicit conversions not working with type parameters隐式转换不适用于类型参数
【发布时间】:2012-04-01 19:08:48
【问题描述】:

我遇到了隐式转换在某些情况下(更高种类的类型)不起作用的问题。给定一个系统、一个表达式类型和两个特定的表达式子类型:

trait Sys[S <: Sys[S]]

object Expr {
  trait Var  [S <: Sys[S], A] extends Expr[S, A]
  trait Const[S <: Sys[S], A] extends Expr[S, A]
}
trait Expr[S <: Sys[S], A]

还有一个用于表达式操作的 pimp 类:

class RichDoubleExpr[S <: Sys[S]](ex: Expr[S, Double]) {
  def gugu(): String = "yes"
}

然后让有从原语到表达式,从表达式到表达式操作的隐式转换:

implicit def const[S <: Sys[S]](d: Double): Expr[S, Double] = 
  new Expr.Const[S, Double] {}

implicit def exprOps[S <: Sys[S], A <% Expr[S, Double]](v: A): RichDoubleExpr[S] = 
  new RichDoubleExpr( v )

以下工作(因此是隐式方法const):

3.4.gugu()

以下不起作用(因此是隐式方法exprOps):

def test[S <: Sys[S]]: String = {
  val v = new Expr.Var[S, Double] {}
  v.gugu()
}

出现以下错误:

error: No implicit view available from java.lang.Object with
   Expr.Var[S,Double] => Expr[S,Double].
          v.gugu()
          ^

现在,由于 Expr.Var 扩展了 Expr 并且类型参数相同,因此该错误消息显然对我没有意义。任何想法如何解决这个问题?

【问题讨论】:

    标签: scala implicit-conversion higher-kinded-types


    【解决方案1】:

    在我的情况下,一个可行的解决方案是稍微“修复”类型参数S

    class ExprImplicits[S <: Sys[S]] {
      implicit def const(d: Double): Expr[S, Double] = new Expr.Const[S, Double] {}
    
      implicit def exprOps[A <% Expr[S, Double]](v: A): RichDoubleExpr[S] = 
        new RichDoubleExpr(v)
    }
    

    现在我可以为特定系统导入隐式:

    def test[S <: Sys[S]]: String = {
      val imp = new ExprImplicits[S]
      import imp._
    
      3.4.gugu()  // ok
      val v = new Expr.Var[S, Double] {}
      v.gugu()    // ok
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-07
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多