首页 > 解决方案 > 是什么让 scala 中的类/特征成为 ADT

问题描述

将 Scala 特征/类归类为 ADT 的要求是什么

标签: scalatypesalgebraic-data-types

解决方案


代数数据类型是一种复合类型,即由其他类型组合而成的类型。

定义取自维基百科

什么是产品类型?

class Person(name: String, age: Int)

人物类型由姓名和年龄类型组合而成。

您需要 name 和 age 来构造 Person 类型。含义 Person 是姓名和年龄类型的乘积(代数乘积,而不是数学乘积)。

什么是 sum 类型?

trait Closable
class File(path: String) extends Closable
class Socket(port: Int) extends Closable

Closable 可以由 File 或 Socket 创建。其中一个就足以创建一个 Closable 实例。File 和 Socket 被称为 sum 类型。

为什么sealed

密封不是强制性的,但它的良好做法。

使用时会发生什么sealed

sealed trait Closable
class File(path: String) extends Closable
class Socket(port: Int) extends Closable

您不能在另一个文件中声明另一个 Closable 子类型。所有子类型都必须出现在单个文件中。这会阻止模式匹配给出匹配错误。所有子类型都在一个文件中,并且只有库作者才能添加更多子类型(如果是库)。

为什么case

case 是由 scala 编译器生成的

  1. 具有 apply、applySeq、unapply 和 unapplySeq 方法的类伴随对象
  2. 此外,equals、copy、toString 等也会自动生成
  3. 它有助于在模式匹配时解构案例类。

怎么样fold

fold 完全是另一个概念,它与 ADT 无关

最后,ADT 看起来像这样

sealed trait Closable
case class File(path: String, name: String) extends Closable
case class Socket(port: Int) extends Closable

也可以有抽象类

sealed abstract class Closable
case class File(path: String, name: String) extends Closable
case class Socket(port: Int) extends Closable

Haskell ADT

data Closable = File { path :: String, name :: String } | Socket { port :: Int }

但是,在 Scala 中,sum 类型是使用继承来模拟的


推荐阅读