在玩Scalaz.Tag
时,我发现了一个奇怪的比较结果。
import scalaz._, Scalaz._, Tags._, syntax.tag._
test("Creating Tagged type") {
sealed trait USD
sealed trait EUR
def USD[A](amount: A): A @@ USD = Tag[A, USD](amount)
def EUR[A](amount: A): A @@ EUR = Tag[A, EUR](amount)
val oneUSD = USD(1)
2 * oneUSD.unwrap shouldBe 2
def convertUSDtoEUR[A](usd: A @@ USD, rate: A)
(implicit M: Monoid[A @@ Multiplication]): A @@ EUR =
EUR((Multiplication(usd.unwrap) |+| Multiplication(rate)).unwrap)
convertUSDtoEUR(USD(1), 2) === EUR(2) // true
convertUSDtoEUR(USD(1), 2) === USD(2) // true
convertUSDtoEUR(USD(1), 2) shouldBe EUR(2) // true
convertUSDtoEUR(USD(1), 2) shouldBe USD(2) // true
}
我想区分不同的密封特性。这是scalaz.Tag
的预期行为,还是我错过了什么?
更新
由于=:=
===
内使用 scalaz org.scalatest.FunSuite
,因此我实施了org.scalactic.TripleEqualSupport
trait FunTestSuite
extends FunSuite
with Matchers
with BeforeAndAfterEach
with BeforeAndAfterAll
with TestImplicits
trait TestImplicits {
final case class StrictEqualOps[A](val a: A) {
def =:=(aa: A) = assert(a == aa)
def =/=(aa: A) = assert(!(a == aa))
}
implicit def toStrictEqualOps[A](a: A) = StrictEqualOps(a)
}
// spec
convertUSDtoEUR(USD(1), 2) =:= EUR(2)
convertUSDtoEUR(USD(1), 2) =:= EUR(3) // will fail
convertUSDtoEUR(USD(1), 2) =:= USD(3) // compile error
答案 0 :(得分:2)
您正在使用scalatest中的===
和shouldBe
。它们只检查运行时值,而不是类型(它们委托给==
)。如果要区分类型,则必须使用scalaz中的===
。