是什么让scala中的class / trait成为ADT

时间:2018-06-15 12:51:12

标签: scala types algebraic-data-types

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

  • 是scala和ADT中的所有密封特征/类吗?或者是否需要更多属性才能成为ADT,例如支持方法fold
  • 密封特征/类的所有实现都应该是case类吗? 文档here说明如下

      

    代数数据类型(ADT)之间的自动映射(编码为   Scala作为案例类和密封特征)和这些通用的   表示。

1 个答案:

答案 0 :(得分:3)

  

代数数据类型是一种复合类型,即通过组合其他类型形成的类型。

取自维基百科的定义

什么是产品类型?

class Person(name: String, age: Int)

通过组合名称和年龄类型形成人员类型。

您需要名称和年龄来构建Person类型。含义人是名称和年龄类型的产品(代数产品,而不是数学产品)。

什么是总和类型?

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

Closable可以通过File或Socket创建。其中一个就足以制作一个Closable实例。文件和套接字称为和类型。

为什么sealed

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

使用sealed时会发生什么?

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

您不能在另一个文件中声明另一个子类型的Closable。所有子类型都必须以单个文件存在。这样可以阻止模式匹配,从而产生Match Error。所有子类型都在一个文件中,只有库作者才能添加更多的子类型(如果是库)。

为什么case

是scala编译器生成

的情况
  1. 使用apply,applySeq,unapply和unapplySeq方法的类伴随对象
  2. 此外,equals,copy,toString等也会自动生成
  3. 当模式匹配时,它有助于解构案例类。
  4. 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 ADTs

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

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