scala类型隐式歧义

时间:2017-06-04 15:16:10

标签: scala polymorphism typeclass implicit

我在代数类型层次结构中设置类型类时遇到问题。

我有以下特点:

trait Field[F]{...}

trait VectorSpace3[V,F] extends Field[F]{...}

知道我想提供实施:

trait DoubleIsField extends Field[Double]{
   ...
}

trait DoubleTurple3IsVectorSpace3 extends VectorSpace3[(Double,Double,Double), Double] with Field[Double]{
   ...
}
trait MyOtherClassIsVectorSpace3 extends VectorSpace3[MyOtherClass, Double] with Field[Double]{
   ...
} 

//now the implicits
implicit object DoubleIsField extends DoubleIsField  
implicit object DoubleTurple3IsVectorSpace3 extends DoubleTurple3IsVectorSpace3 with DoubleIsField
implicit object MyOtherClassIsVectorSpace3 extends MyOtherClassIsVectorSpace3 with DoubleIsField 

最后两个含义导致含糊不清:DoubleIsField是3个隐式值的一部分,代码无法编译。如何在scala中处理这个问题?

编辑:

错误:

ambiguous implicit values:
[error]  both object DoubleIsField in object TypeClasses of type 
Russoul.lib.common.TypeClasses.DoubleIsField.type
[error]  and object DoubleTurple3IsVectorSpace3 in object TypeClasses of type 
Russoul.lib.common.TypeClasses.DoubleTurple3IsVectorSpace3.type
[error]  match expected type Russoul.lib.common.TypeClasses.Field[...Double]

EDIT2:

 def func()(implicit env: Field[Double]): Unit ={

 }

 func()

完整的测试计划:

object Test extends App {

trait Field[F]{

}

trait VectorSpace3[V,F] extends Field[F]{

}
trait DoubleIsField extends Field[Double]{

}

trait DoubleTurple3IsVectorSpace3 extends VectorSpace3[(Double,Double,Double), Double] with Field[Double]{

}


//now the implicits
implicit object DoubleIsField extends DoubleIsField
implicit object DoubleTurple3IsVectorSpace3 extends DoubleTurple3IsVectorSpace3 with DoubleIsField


def func()(implicit env: Field[Double]): Unit ={

}

func()

}

1 个答案:

答案 0 :(得分:1)

(根据您最近的评论更新...)

问题是以下功能的定义:

def func()(implicit env: Field[Double]): Unit = {
  // ...
}

您的问题是您在同一范围内有多个implicit此类型的值,因此编译器无法知道要提供哪一个(它们都是隐式值,可以表示为类型为{{ 1}})。

关于Field[Double]参数值的重点是编译器可以识别单个值;如果它不能识别一个,它就无法读出你的想法并选择正确的一个,也不希望它随机选择一个。

您可以使用的选项如下:

  • 使用implicit参数值并明确地将值传递给您的函数。
  • 使用implicit参数更改函数的定义,使其成为具有唯一implicit值的类型。
  • 使用单个implicit定义。 (最初在列表中遗漏了这个道歉。)