了解榆树联盟类型

Gee*_*rts 5 elm union-types

我在榆树的联合类型中缠绕着一些麻烦.我理解简单的用例就像

type Visibility = All | Active | Completed
Run Code Online (Sandbox Code Playgroud)

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

type Msg
   = OnFetchMails (WebData (List Mail))
   | OnFetchSmss (WebData (List SMS))
Run Code Online (Sandbox Code Playgroud)

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

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

Ale*_*Lew 11

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

type Visibility 
  = All 
  | Active 
  | Completed
Run Code Online (Sandbox Code Playgroud)

正如你所推测的那样,这会声明类型Visibility并定义三个值,所有类型都是如此Visibility.构造类型值的唯一方法Visibility是使用这三个选项之一.因此,我们经常称它们为"构造函数".

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

type TrainStatus
  = OnTime
  | Delayed Int
Run Code Online (Sandbox Code Playgroud)

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

OnTime  : TrainStatus
Delayed : Int -> TrainStatus
Run Code Online (Sandbox Code Playgroud)

OnTime构造函数采用零个参数,所以是一个简单的值; 它已经是一个TrainStatus.但是,Delayed声明为一个参数的构造函数:它是一个函数创建一个新TrainStatus的出来Int.因此,Delayed 5,Delayed 10,和Delayed 100都是有效的TrainStatus值.(我们可以将它们解释为"延迟5分钟"或类似的东西.)

构造函数可以使用多个参数; 例如,如果我们想要作为String包含延迟的原因:

type TrainStatus
  = OnTime
  | Delayed Int String

ts : TrainStatus
ts = Delayed 20 "The conductor took a short nap."
Run Code Online (Sandbox Code Playgroud)

它定义了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
Run Code Online (Sandbox Code Playgroud)


Mat*_*ton 7

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

type Msg
    = OnFetchMails (WebData (List Mail))
    | OnFetchSmss (WebData (List SMS))
Run Code Online (Sandbox Code Playgroud)

意味着类型的值Msg可以是,或者OnFetchMails具有某种类型的值WebData (List Mail); 或者它可以是OnFetchSmssWebData (List SMS)伴随它.

它们有时被称为标记联合,因为它们的行为很像C样式的union构造,其中包含一个标记值,该标记值表示union中的哪个选项是当前有效的(并且实际上有许多具有此类结构的语言)以这种方式实现它们).

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