F#中被歧视联盟的含义

时间:2014-08-18 09:21:08

标签: f# discriminated-union

我确实理解"歧视"和"联盟"在他们独立的背景下,但是我对F#"被歧视的联盟"而感到茫然。

Fyi,英语不是我的第一语言,我也不擅长数学。所以我希望有人可以对F#的这个特性有所了解。请。

我需要知道的是:

  • 这种歧视联盟的用例。它通常用于什么?
  • 它等同于其他OOP功能/条款。如果有的话。
  • 是否就像我们使用维恩图来表示数据的设置操作一样?

或者你可以帮我指点链接。

2 个答案:

答案 0 :(得分:8)

歧视联盟是两个联合体,你可以告诉你哪个项目最初属于哪个集合;即使它们是同一个东西,你也可以在它们之间区分,即分开它们。

例如,如果你有两组整数的区别联合,两者都包含数字2,你可以区分2,因为你知道它来自哪个原始集。

例如,考虑二维平面中的点。

这些可以用两种方式表示为一对实数,使用矩形(或笛卡尔)坐标(x coordinate, y coordinate)或使用极坐标(angle of rotation, distance)

但如果有人给你一对数字,你就不会知道他们的意思。

我们可以形成一个有区别的联盟,但是:

type Point2D = 
    | Rectangular of real * real
    | Polar of real * real

现在任何Point2D值都会使预期的解释清晰,编译器可以确保我们不会尝试混合表示或无法处理案例。

在OO设置中,您将使用抽象基类构建类层次结构,或者使用" kind"你可以检查的成员。

但是,形成不同类型的联合会更常见 - 如果你为编程语言编写了一个解释器,你可能会有类似的东西

type Expression = 
    | Integer of int
    | String of string
    | Identifier of string
    | Operator of string
    | Conditional of Expression * Expression * Expression
    | Definition of string * Expression

等等。

被识别的工会也被称为"总和类型",并且元组被称为"产品类型"。
这些术语来自类型代数学科,结果类型称为"代数数据类型"。
(当功能程序员提及" ADT"时," A"通常用于"代数",而不是"摘要&#34 ;.)

答案 1 :(得分:4)

问题非常广泛,但我会尝试给出一个简单的回答。

您可以将DUP视为 Enums类固醇 - 您可以定义具有不同情况的新数据类型 - 就像枚举一样 - 但除此之外每种情况都可能(或可能不是) )包含其他数据。

一个简单的例子可能是:

type Contact =
  | Email of String
  | Phone of String
  | None

对于类固醇的D Enum,所以是模式匹配而不是switch,您可以在其中解构数据

let contactToString = function
  | Email e -> e
  | Phone p -> p
  | None    -> "no conctact given"

基本上你总是在F#和其他FP语言中使用DU来以明显的方式构建数据 - 你从中获得了很多 - 例如编译器会在你错过案例时发出警告,......)

OOP中的等价物(实际上它被编译成非常相似的东西)是一个基类Contact,其中包含每个案例的子类(EmailContact : Contact等),其中包含数据 - 一部分。

但是有一个重要的区别:你可以扩展这样的OOP继承结构,但你不能外部扩展DUs。 (见Expression-Problem)。

最后:不管它与venn-diagramms或set-theory或其他任何事情无关。

与数学的关系是,这种结构被称为代数数据类型和类型,因为如果你计算这些类型的不同值,你必须< em>总结每个案例的价值。 (也见元组 - 出于类似原因产品类型