2017-05-04 90 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