2017-05-04 86 views
5

我有一些麻烦缠绕在榆树工会类型的头上。我理解的简单的例子像了解榆树工会类型

type Visibility = All | Active | Completed 

这样就意味着可视性的价值可全部或已完成。到现在为止还挺好。然而,我感到困惑的是

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

我应该如何理解?这是否意味着Msg可以是类型函数OnFetchMails,它需要一个类型函数WebData来接收邮件列表?或者我应该如何解释这一点? 我不认为(WebData (List Mail))是有效载荷?

搞笑的是我能得到它,而不理解它

回答

6

其实,是的,你可以把它作为与每个分支一起去的有效载荷工作。

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

就是说Msg类型的值可以是OnFetchMails,这将有WebData (List Mail)类型的一些值去与它;或者它可以是OnFetchSmss并伴随着WebData (List SMS)

他们有时也被称为标签联合,因为他们的行为很像C风格union结构捆绑了一个标签值说哪个选项在工会是当前有效的一个(事实上许多具有这种结构的语言以这种方式实现它们)。

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

8

定义联合类型时,列出了构造该类型值的所有方法。在最简单的形式,这个定义是这样的:

type Visibility 
    = All 
    | Active 
    | Completed 

正如您所推测,这种声明的类型Visibility并定义了三个值,所有Visibility类型。构建Visibility类型值的唯一方法是使用这三个选项之一。因此,我们经常称他们为“构造者”。

这里有一个稍微更复杂的联合类型定义:

type TrainStatus 
    = OnTime 
    | Delayed Int 

正如你所期望的,这定义了两个新的“构造” OnTimeDelayed。但看看他们的类型:

OnTime : TrainStatus 
Delayed : Int -> TrainStatus 

构造函数OnTime零参数,所以只是一个值;它已经是TrainStatus。但Delayed被声明为单参数构造函数:它是一个函数,它从Int中创建一个新的TrainStatus。因此,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