猫'Eq`的'===`与最新的

时间:2017-11-26 23:09:28

标签: scala scala-cats

我正在阅读Scala with Cats,在本书的第一章中,他们描述了Eq的用法。

其中一个练习是编写一个类型类的实例来验证两个 cats 的相等性。考虑一下:

模型

final case class Cat(name: String, age: Int, color: String)

类型类实例

import cats.Eq
import cats.syntax.eq._
import cats.instances.string._
import cats.instances.int._
import co.alejandrome.typeclass.model.Cat

object CatsEqInstances {

  implicit val catsEq: Eq[Cat] = Eq.instance[Cat] {
    (cata, catb) =>
      cata.color === catb.color && cata.age === catb.age && cata.name === catb.name
  }

}

单元测试

import co.alejandrome.typeclass.model.Cat
import org.scalatest.{FlatSpec, Matchers}
import cats.instances.option._

class EqTest extends FlatSpec with Matchers{

  import CatsEqInstances._

  "Eq" should "compare two cats" in {
    val cat1 = Cat("Garfield",   38, "orange and black")
    val cat2 = Cat("Heathcliff", 33, "orange and black")

    catsEq.eqv(cat1, cat2) shouldBe false

    val cat3 = Cat("Garfield",   38, "orange and black")

    catsEq.eqv(cat1, cat3) shouldBe true
  }

  it should "compare two Optional cats" in {
    val cat1 = Cat("Garfield",   38, "orange and black")
    //val cat2 = Cat("Heathcliff", 33, "orange and black")

    val optionCat1 = Option(cat1)
    val optionCat2 = Option.empty[Cat]

    optionCat1 === optionCat2
  }

}

第一个测试工作正常,但第二个测试没有,因为===运算符是最新的运算符,而不是Eq运算符。

我探究了类型类是否有任何语法或暗示,但我找不到任何关于它的内容。我在this PR中看到了基于Bill Venner's solution的解决方案,但这仅适用于猫自己的单元测试。

我用EqSyntax特征戳了戳但是我无法弄明白如何覆盖自己实施===

有没有办法做到这一点?或者这还没有实现?

由于

1 个答案:

答案 0 :(得分:2)

我不确定我是否正确理解了您的问题,但看起来您可以根据您引用的PR重新使用Cats为自己的测试实现的内容。只需将测试类定义更改为

即可
class EqTest extends FlatSpec with Matchers with cats.tests.StrictCatsEquality  {

然后你可以编写诸如

之类的测试
optionCat1 === optionCat2 shouldBe false

optionCat1 should !== (optionCat2)

并且他们将使用您的Eq[Cat]定义(如果它被导入范围)。

基本上,我们的想法是ScalaTest ===使用一些隐含的CanEqual。因此,如果您提供(导入)自定义隐式实现 - 您可以更改===在其中的工作方式。