【问题标题】:Optional Fields, ADT, or?可选字段、ADT 还是?
【发布时间】:2016-08-24 19:09:48
【问题描述】:

给定一个A,它可能有可选字段ab

case class A(a: Option[Int], b: Option[String])

我可以将A 定义为Algebraic Data Type

但是,每个None/Option 选择需要 4 个子类:

sealed trait AADT
case class Aa(a: Int) extends AADT
case class Aab(a: Int, b: String) extends AADT
case class Ab(b: String) extends AADT
case object Neither extends AADT

我认为这个 ADT 比上面的 A 选项更可取,后者具有 Option 类型。

但是,这种类型在 3、4 等字段时可能会很快失控。

是否有第三种方法来实现A,即不使用我的第一个或第二个实现?

【问题讨论】:

  • 你意识到 Option[A] 本身就是一个 ADT 对吧?
  • 我反对你的提议的第一个想法是认为 Option 本身已经提供了一些有用的方法,如 map、flatMap、filter 等。但另一方面,A 是单态的。
  • 一种尝试过的方法(实际上很无聊)是使用(Option[Int], Option[String])。但为了弥补这种无聊,我提供了第四个选项,使用 Int、String、(Int, String) 和两者的无形联积。
  • @pedrofurla 我看不出在这种情况下使用Tuple 与案例类有何不同。请让我知道您看到了什么优势。
  • @KevinMeredith 如果您还不熟悉该主题,您可能会对youtube.com/watch?v=YScIPA8RbVE 感兴趣。它需要一些 Haskell 知识,如果您需要,我很乐意提供帮助(不过非常基础)。

标签: scala


【解决方案1】:

代数上还有第三个选项涵盖所有组合

sealed trait A
case class Ao(o: Option[(Int, String)]) extends A //all or none
case class Ae(e: Either[Int, String]) extends A //first or second

如果每种情况都有单独的域名,我肯定会选择某种 ADT。

可选字段适用于数据传输对象 (DTO)

【讨论】:

  • 好收获!真的很喜欢。
【解决方案2】:

这是我想到的第一件事,将其发布在评论部分很难阅读。这绝对不是一个最漂亮的解决方案,但对于 OP 的情况来说可能“足够好”。

sealed trait AADT
case class Aa(a: Int) extends AADT
case class Aab(a: Int, b: String) extends AADT
case class Ab(b: String) extends AADT
case object Neither extends AADT

object AADTBuilder {
  def apply() = Neither
  def apply(a: Int) = Aa(a)
  def apply(a: Int, b: String) = Aab(a, b)
  def apply(b: String) = Ab(b)
}

只需使用正确的参数调用AADTBuilder

【讨论】:

  • 我认为问题不在于如何构建,而在于如何构建。
  • 是的,我看错了,会留下答案,因为有人可能会觉得很方便@pedrofurla
猜你喜欢
  • 2017-02-28
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2020-10-11
  • 2014-02-12
  • 1970-01-01
相关资源
最近更新 更多