Edited at

`org.scalatest.Matchers._`と`org.scalactic.Tolerance._`を同時にimportすると、`+-`の呼び出しでエラー発生

More than 1 year has passed since last update.


環境


  • Scala 2.12.5


    • sbt 1.1.3

    • ScalaTest 3.0.5




やりたいこと

Scalaのテストコードで、浮動小数点数の比較をしたいです。

ScalacticのToleranceトレイトで定義されている+-メソッドを、使います。

http://www.scalactic.org/user_guide/Tolerance


問題

以下のテストコードを実行したら、+- is not a memberというエラーが発生しました。


SampleTest.scala

import org.scalatest.FreeSpec

import org.scalatest.Matchers._
import org.scalactic.Tolerance._

class SampleTest extends FreeSpec {

"tolerance test" in {
2.00001 shouldBe (2.0 +- 0.01)
}
}



sbt_console

>testOnly SampleTest

[error] SampleTest.scala:12:29: value +- is not a member of Double
[error] 2.00001 shouldBe (2.0 +- 0.01)
[error] ^
[error] one error found
[error] (Test / compileIncremental) Compilation failed



解決

import org.scalactic.Tolerance._文を削除したら、エラーは発生しませんでした。


原因


ライブラリのソースを参照

SampleTestがimportしているMatchersは、Toleranceトレイトをミックスインしています。


org.scalactic.Matchers.scala

trait Matchers extends Assertions with Tolerance with ShouldVerb with MatcherWords with Explicitly { matchers =>

}



org.scalactic.Tolerance.scala

trait Tolerance {

final class PlusOrMinusWrapper[T: Numeric](pivot: T) {

def +-(tolerance: T): Spread[T] = {
//...
}
}

import scala.language.implicitConversions

implicit def convertNumericToPlusOrMinusWrapper[T : Numeric](pivot: T): PlusOrMinusWrapper[T] = new PlusOrMinusWrapper(pivot)
}



Scala Compiler Option-Xlog-implicits

scalacのオプションには、「implicitが適用されない理由」を教えてくれる、-Xlog-implicitsというオプションがあります。


-Xlog-implicit-conversions

Print a message whenever an implicit conversion is inserted.


https://docs.scala-lang.org/overviews/compiler-options/index.html

build.sbtにscalacのオプションを設定して、テストを実行しました。


build.sbt

scalacOptions ++= Seq("-Xlog-implicits")

scalaVersion := "2.12.5"


sbt_console

>testOnly SampleTest

[info] SampleTest.scala:12:25: <convertNumericToPlusOrMinusWrapper: error> is not a valid implicit value for Double(2.0) => ?{def +-: ?} because:
[info] reference to convertNumericToPlusOrMinusWrapper is ambiguous;
[info] it is imported twice in the same scope by
[info] import org.scalactic.Tolerance._
[info] and import org.scalatest.Matchers._
[info] 2.00001 shouldBe (2.0 +- 0.01)
[info] ^
[error] SampleTest.scala:12:29: value +- is not a member of Double
[error] 2.00001 shouldBe (2.0 +- 0.01)
[error] ^
[error] one error found


implicitに関する情報が出力されました。

内容は、以下の通りです。



  • convertNumericToPlusOrMinusWrapperへの参照が曖昧


  • org.scalactic.Tolerance._org.scalatest.Matchers._で、同じスコープ内で二重にimportされている