While playing with Scalaz.Tag
, I found that an weird comparison result.
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
}
I would like to distinguish different sealed traits. Is this intended behavior of scalaz.Tag
or am i missing something?
Updated
I implemented =:=
as I can't use scalaz ===
inside org.scalatest.FunSuite
due to 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
You are using ===
and shouldBe
from scalatest. They only check the runtime value, not the types (they delegate to ==
). If you want to distinguish the type, you'll have to use ===
from scalaz.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.