聯集型別(Union types)

Elm 的聯集型別非常有彈性並廣泛應用在許多地方。聯集型別看起來像是:

type Answer = Yes | No

Answer 可以是 YesNo。聯集型別非常有用,讓程式碼更加泛用。舉例來說,函式可以定義成:

respond : Answer -> String
respond answer =
    ...

第一個引數接受 YesNo,例如 respond Yes 就是個合法呼叫。

聯集型別通常也稱為標籤(tags)

裝載(Payload)

聯集型別可以關聯額外訊息:

type Answer = Yes | No | Other String

上述例子中,Other 標籤有關聯字串。你可以像這樣呼叫 respond

respond (Other "Hello")

這裡要用括號包起來,不然 Elm 會當作傳遞 2 個參數到 respond 函數。

如同函式建構子

注意到我們如何裝載 Other

Other "Hello"

就像是個函式呼叫,而 Other 就是那個函式。聯集型別表現像是函式。舉例來說,給定某一型別:

type Answer = Message Int String

你可以用下列語法新增 Message 標籤:

Message 1 "Hello"

你也可以相其他函式一樣使用套用函式。通常稱之為 建構子(constructors),因為你可以使用這個方式來建構出完整的型別,換言之,使用 Message 作為函式來建構 (Message 1 "Hello")

巢狀

聯集型別中巢狀引用其他的聯集型別十分常見。

type OtherAnswer = DontKnow | Perhaps | Undecided

type Answer = Yes | No | Other OtherAnswer

這樣你就可以傳遞到 respond 函式(預期 Answer),像是:

respond (Other Perhaps)

型別變數

你也可能需要用到型別變數或替身:

type Answer a = Yes | No | Other a

Answer 就可以使用不同的型別,例如 Int、String。

舉例來說,respond 可能看起來像是:

respond : Answer Int -> String
respond answer =
    ...

透過使用 Answer Int 標記式,表示 a 為型別 Int 的替身。

所以當我們需要呼叫 respond 時,語句為:

respond (Other 123)

但是,若語句為 (Other "Hello") 則會失效,因為 respond 預期 a 的位置是個整數。

常見用法

一個常見的用法是,使用聯集型別來互相傳遞資料,這樣就可以知道可能的型別值。

舉理來說,典型的網頁應用程式中,包含了許多動作,例如:讀取使用者、新增使用者、刪除使用者⋯等。某些動作可能會裝載其他資料。

聯集型別常見用法為:

type Action
    = LoadUsers
    | AddUser
    | EditUser UserId
    ...

聯集型別還有更多細節。如果有興趣請參考這裡

results matching ""

    No results matching ""