了解榆树联盟类型

时间:2017-05-04 13:55:12

标签: elm union-types

我在榆树的联合类型中遇到了一些麻烦。我理解像

这样简单的用例
type Visibility = All | Active | Completed

这意味着Visiblity的值可以是All,Active或Completed。到现在为止还挺好。我感到困惑的地方是

type Msg
   = OnFetchMails (WebData (List Mail))
   | OnFetchSmss (WebData (List SMS))

我该如何解读?这是否意味着Msg可以是类型函数OnFetchMails,它采用一个带有邮件列表的类型函数WebData?或者我该如何解释? 我不认为(WebData (List Mail))是有效载荷吗?

有趣的是,我可以在不理解它的情况下让它工作

2 个答案:

答案 0 :(得分:11)

定义联合类型时,列出构造该类型值的所有方法。在最简单的形式中,该定义如下所示:

type Visibility 
  = All 
  | Active 
  | Completed

正如您所推测的那样,这会声明类型Visibility并定义三个值,所有类型都为Visibility。构造Visibility类型值的唯一方法是使用这三个选项之一。因此,我们经常称他们为#34;施工人员。"

这是一个稍微复杂的联合类型定义:

type TrainStatus
  = OnTime
  | Delayed Int

正如您所料,这定义了两个新的"构造函数," OnTimeDelayed。但看看他们的类型:

OnTime  : TrainStatus
Delayed : Int -> TrainStatus

OnTime构造函数接受零参数,因此只是一个值;它已经是TrainStatus了。但是Delayed被声明为单参数构造函数:它是一个函数,可以从TrainStatus中创建一个新的Int。因此,Delayed 5Delayed 10Delayed 100都是有效的TrainStatus值。 (我们可以将它们解释为"延迟5分钟"或类似的东西。)

构造函数可以接受多个参数;例如,如果我们想要作为字符串包含延迟的原因:

type TrainStatus
  = OnTime
  | Delayed Int String

ts : TrainStatus
ts = Delayed 20 "The conductor took a short nap."

定义Delayed : Int -> String -> TrainStatus

如果您获得TrainStatus,则可以使用模式匹配提取其中的IntString

case ts of
  OnTime ->
    "Your train is on time!"

  Delayed minutes reason ->
    "Your train has been delayed by " ++ toString minutes ++ " because " ++ reason

答案 1 :(得分:7)

实际上,是的,您可以将其视为与每个分支一起的有效载荷。

type Msg
    = OnFetchMails (WebData (List Mail))
    | OnFetchSmss (WebData (List SMS))

表示Msg类型的值可以是OnFetchMails,其值为WebData (List Mail)的值为OnFetchSmss;或者可以WebData (List SMS)附加union

他们有时称为标记的联盟,因为它们的行为很像C样式的Msg构造,其中包含标记值说联盟中哪个选项是当前有效的选项(事实上,许多具有这种结构的语言都是这样实现的。)

它们也可以被建模为抽象基类{{1}}类型的一系列子类,为每个子类中的有效负载添加存储,并要求将有效负载作为构造函数参数提供。