scala - scala的“案例类”中的“案例”一词是什么意思?
问题描述
我知道这case class
会导致编译器class
使用样板来增加 a 以实现某种有用的模式(“应完全依赖于其构造函数参数的普通且不可变的数据保存对象”)。
但是在这种情况下,“案例”这个词本身对我来说没有任何意义。我习惯于将它用作switch
C# 语句的一部分,但这似乎与 Scala 对这个词的使用无关。
当我可以将单词附加到特定含义时,我发现编程更容易。现在我的心智模式是case => boilerplate
一样的blurg => boilerplate
。这是一个有效的心智模型,但模棱两可容易让人误解或完全忘记。
那么这个词case
与编译器的实际工作有什么关系呢?
我不是在寻找“设计师的想法”,而是“考虑到语言设计的一般知识,将这个术语与其含义联系起来的合理方式是什么”。
解决方案
在我看来,该术语case
来自案例分析,这是一种由称为代数数据类型的特殊结构启用的推理技术。本身 可能没有多大意义,但是当它构成结构的一部分时case
,这就是 Scala 定义 ADT 的方式,例如case class
sealed
sealed trait Number
case object Zero extends Number
case class Succ(v: Number) extends Number
那么我们看到构造s有两种形式Number
,分别是usingZero
和Succ
constructors。因此,每当我们必须考虑Number
s 时,我们至少知道有两个不同case
的 s 需要考虑。例如,假设我们要在Number
s 上定义加法,那么它的定义将不得不处理两种情况,也许,像这样
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 语言中,简单地用竖线表示,就像这样object
trait
case class
|
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
我的建议是尽量不要成为“语言的奴隶”,而是应该为你服务。重要的是单词或术语背后的含义,而不是单词本身。不要围绕术语建立心智模型,而是围绕他们努力跨越微弱的沟通桥梁的沉重概念建立心智模型。在我看来,case
试图传达的概念是 ADT 的概念。
推荐阅读
- r - 在 split-apply-combine 中使用 map() 来运行具有回归权重的多个回归
- r - 在 ggplot2 log10 轴上以十的整数幂中断
- linux - 在linux(Jenkins)中的字符串匹配正则表达式之前添加新行
- python - 如何在自定义 DeleteView 中重定向到上一页?
- python-3.x - 如何准备python代码以在不同环境下从命令行运行?
- java - Spring Jpa批量插入整个数据或更新实体的某些字段(如果已经可用)
- c# - 在对象初始化器中重新排列属性的可能性
- tfs - 向“按测试用例 ID 获取套件”发送请求时得到空响应
- laravel - 如何从 Laravel 中的字符串中获取非数字字符
- javascript - 如何在反应项目和 Firebase 中使用带有 axios 的删除请求?