首页 > 解决方案 > scala的“案例类”中的“案例”一词是什么意思?

问题描述

我知道这case class会导致编译器class使用样板来增加 a 以实现某种有用的模式(“应完全依赖于其构造函数参数的普通且不可变的数据保存对象”)。

但是在这种情况下,“案例”这个词本身对我来说没有任何意义。我习惯于将它用作switchC# 语句的一部分,但这似乎与 Scala 对这个词的使用无关。

当我可以将单词附加到特定含义时,我发现编程更容易。现在我的心智模式是case => boilerplate一样的blurg => boilerplate。这是一个有效的心智模型,但模棱两可容易让人误解或完全忘记。

那么这个词case与编译器的实际工作有什么关系呢?

我不是在寻找“设计师的想法”,而是“考虑到语言设计的一般知识,将这个术语与其含义联系起来的合理方式是什么”。

标签: scalaterminologycase-class

解决方案


在我看来,该术语case来自案例分析,这是一种由称为代数数据类型的特殊结构启用的推理技术。本身 可能没有多大意义,但是当它构成结构的一部分时case,这就是 Scala 定义 ADT 的方式,例如case classsealed

sealed trait Number
case object Zero extends Number
case class Succ(v: Number) extends Number

那么我们看到构造s有两种形式Number,分别是usingZeroSucc constructors。因此,每当我们必须考虑Numbers 时,我们至少知道有两个不同case的 s 需要考虑。例如,假设我们要在Numbers 上定义加法,那么它的定义将不得不处理两种情况,也许,像这样

def sum(a: Number, b: Number): Number =
  a match {
    case Zero => b
    case Succ(v) => Succ(sum(v, b))
  }

在哪里

sum(Succ(Zero), Succ(Zero)) == Succ(Succ(Zero)) // 1 + 1 = 2
sum(Succ(Succ(Zero)), Succ(Zero)) == Succ(Succ(Succ(Zero))) // 2 + 1 = 3
sum(Succ(Zero), Succ(Succ(Zero))) == Succ(Succ(Succ(Zero))) // 1 + 2 = 3
sum(Zero, Succ(Succ(Zero))) == Succ(Succ(Zero)) // 0 + 2 = 2
sum(Succ(Succ(Zero)), Zero) == Succ(Succ(Zero)) // 2 + 0 = 2

请注意 Scala 为了定义 ADT 是如何使用、等术语的class,这些术语似乎来自面向对象的范式,但是 ADT 在概念上与 OO 中的类层次结构几乎没有共同之处。我个人觉得这很令人困惑,但我们必须记住 Scala 既是函数式语言又是 OO 语言,这可能是这种术语溢出的原因。在其他一些更“纯”的 ADT 语言中,简单地用竖线表示,就像这样objecttraitcase class|

Inductive nat : Type :=
   | O : nat
   | S : nat -> nat.

我的建议是尽量不要成为“语言的奴隶”,而是应该为你服务。重要的是单词或术语背后的含义,而不是单词本身。不要围绕术语建立心智模型,而是围绕他们努力跨越微弱的沟通桥梁的沉重概念建立心智模型。在我看来,case试图传达的概念是 ADT 的概念。


推荐阅读