在具有子类型的类上创建 Scalaz 相等实例

2024-03-26

我有以下简单的 ADT,如何实现相等类型类的实例,而不求助于显式模式匹配所有可能的组合?

import scalaz._
import Scalaz._

sealed trait Billinginfo
case class CreditCard(number: Int, holder: String, Address: String) extends Billinginfo
case object COD extends Billinginfo
case class Invoice(cId: String) extends Billinginfo

object Billinginfo{

  implicit val BillingEqual = Equal.equal[Billinginfo]{(b1,b2) =>
    (b1,b2) match {
      case (Invoice(c1), Invoice(c2)) => c1 === c2
      case (CreditCard(a,b,c), CreditCard(d,e,f)) =>
        a === d &&
        b === e &&
        c === f //writing exhaustive match would be tedious
    }
  }

你有(至少)两个选择。一是使用“自然”平等。如果您没有任何案例类成员的自定义类型,这应该可以正常工作:

implicit val BillingEqual: Equal[Billinginfo] = Equal.equalA[Billinginfo]

或者您可以使用 Shapeless 的类型类实例派生:

import shapeless._
import scalaz.{ Coproduct => _, :+: => _, _ }, Scalaz._

object EqualDerivedOrphans extends TypeClassCompanion[Equal] {
  object typeClass extends TypeClass[Equal] {
    def product[H, T <: HList](eh: Equal[H], et: Equal[T]): Equal[H :: T] =
      tuple2Equal(eh, et).contramap {
        case h :: t => (h, t)
      }

    def project[A, B](b: => Equal[B], ab: A => B, ba: B => A): Equal[A] =
      b.contramap(ab)

    def coproduct[L, R <: Coproduct](
      el: => Equal[L],
      er: => Equal[R]
    ): Equal[L :+: R] = eitherEqual(el, er).contramap {
      case Inl(l) => Left(l)
      case Inr(r) => Right(r)
    }

    val emptyProduct: Equal[HNil] = Equal.equal((_, _) => true)
    val emptyCoproduct: Equal[CNil] = Equal.equal((_, _) => true)
  }
}

import EqualDerivedOrphans._

这将得出Equal任何具有以下特征的案例类的实例Equal其所有成员的实例。

或者当然你可以列举一些情况,这实际上并没有那么可怕:

implicit val BillingEqual = Equal.equal[Billinginfo] {
  case (Invoice(c1), Invoice(c2)) => c1 === c2
  case (CreditCard(a, b, c), CreditCard(d, e, f)) =>
    a === d && b === e && c === f
  case (COD, COD) => true
  case _ => false
}

请注意,您不需要对元组进行额外的匹配级别。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在具有子类型的类上创建 Scalaz 相等实例 的相关文章

  • Scala Swing 库的问题

    您好 我在 2 8 Beta1 prerelease 版本中使用 Scala Swing 库时遇到问题 我有一种情况 我想在 GUI 中显示一个表 并在 SQL 请求返 回结果时更新它 在 Scala 中可以通过哪种方式完成此操作 目前我正
  • 为什么使用散列而不是点来选择 Scala 类型成员?

    在 Scala 中 从类中选择类型的语法与从类中选择其他任何内容的语法不同 因为前者使用散列而不是点作为选择运算符 这是为什么 示例 如果我们有这样的课程 class Example type Foo String 为什么我们要从这样的类中
  • Mockito 在 ScalaTest 中的答案

    有没有 Mockito 的替代品Answer http docs mockito googlecode com hg latest org mockito stubbing Answer html在 Scala 测试中 我正在经历它文档 h
  • 如何让 Kotlin 类型安全构建器在 Scala 中工作?

    Kotlin 很棒类型安全的构建者 https kotlinlang org docs reference type safe builders html这使得创建像这样的 dsl 成为可能 html head title The titl
  • Spark JDBC 仅返回带有列名的数据帧

    我正在尝试使用 Spark JDBC 连接到 HiveTable 代码如下 val df spark read format jdbc option driver org apache hive jdbc HiveDriver option
  • 如何使用 Scala 调度获取 301 重定向中返回的 URL?

    我正在使用斯卡拉dispatch http dispatch databinder net Dispatch htmlHTTP 库 版本 0 10 1 我向返回 HTTP 301 永久重定向的 URL 发出请求 例如 http wikipe
  • scala.collection.Seq 不适用于 Java

    Using 阿帕奇火花2 0 1 Java 7 在 Apache Spark Java API 文档中 DataSet 类出现了一个example http spark apache org docs latest api java org
  • 带尖括号 (<>) 的方法

    方法名称中是否可以有尖括号 例如 class Foo ind1 Int ind2 Int var v new Foo 1 2 v 1 3 updates ind1 v lt 1 gt 4 updates ind2 真实情况显然比这更复杂 我
  • Spark:有没有办法打印出spark-shell和spark的类路径?

    我可以在 Spark shell 中成功运行 Spark 作业 但是当它打包并通过 Spark submit 运行时 我收到 NoSuchMethodError 这向我表明类路径存在某种不匹配 有没有办法可以比较两个类路径 某种日志记录语句
  • Twitter API 与 Scala 2.12 一起使用

    我正在使用 Scala 2 12 使用 SBT 构建 构建 Spark 3 0 0 流应用程序 鉴于所有用于执行此操作的库均适用于 Scala EDIT 我尝试使用库构建时得到的示例输出 object twitter is not a me
  • 一般重写 Scala 案例类

    是否可以通用地替换案例类中的参数 更具体地说 假设我想要一个接收 查找 案例类和 替换 案例类 如语法规则的左侧和右侧 以及目标案例类的替代函数 并且该函数将返回将查找案例类的参数替换为替换案例类的新案例类 该函数还可以简单地采用一个案例类
  • 如何在 Scala 中操作 JSON AST

    我正在尝试 json4s 库 基于 lift json 我想做的一件事是将 JSON 字符串解析为 AST 然后对其进行操作 例如 我想更新插入一个字段 如果该字段不存在 则将该字段插入到 AST 中 如果存在 则更新其值 我无法在文档中找
  • scala 使用 GMPUtil 处理 pidigits

    Rex Kerr 发布了有关在 scala 中使用 GMP 的信息 特别是运行 pidigits 程序 libjpargmp so 使用 GmpUtil c 生成 我的问题是 在哪里可以找到 GMPUtil c 我的谷歌搜索没有发现任何东西
  • Scala 中两个地图的交集和合并/连接

    假设我有两张类似这样的地图 val m1 Map 1 gt One 2 gt Two 3 gt Three val m2 Map 2 gt 2 0 3 gt 3 0 4 gt 4 0 我想根据键获取交集并返回一个表示合并值的元组 结果看起来
  • 我们可以在比赛中重用后卫内部的中间变量吗?

    说我有方法foo as def foo i Int Option Int some code 现在我想在一个Seq of Int如下 Seq 1 2 map case int gt foo int collect case Some int
  • 在 Spark Dataframe 中提取数组索引

    我有一个带有数组类型列的数据框 例如 val df List a Array 1d 2d 3d b Array 4d 5d 6d toDF ID DATA df org apache spark sql DataFrame ID strin
  • Play 框架 2.0:在 Http.Context 中存储值

    我正在尝试在 Play 框架中的 scalaquery 中实现 基于请求 的会话 我使用 scalaquery 创建一个会话 并尝试将其存储在当前的 http 上下文中 如下所示 def withTransaction A bp BodyP
  • 如何从命令行运行scala文件?

    scala是否支持scala run xxx scala go语言支持这样运行 go my go 并且Python支持 python my py 但看来 scala xxx scala 仅进行语法检查 未观察到任何输出或运行行为 那么有没有
  • 运行 JAR 时“JCE 无法验证提供者 BC”

    在我的 scala 项目中我使用 org bouncycastle bcprov jdk14 1 51 用于密码学 如果它在 Scala IDE 中测试我的项目 它工作得很好 但是一旦我制作了一个 JAR 并尝试通过以下方式运行它java
  • 案例类和案例对象之间的区别?

    我正在学习 Scala 和 Akka 并且在最近的查找中solution https stackoverflow com questions 22770927 waiting for multiple results in akka 我发现

随机推荐