Elm 的自訂型別代表固定數量的具名情況,每個值恰好對應其中一種具名情況。
自訂型別使用 type 關鍵字定義,需要的語法非常少。它是 Elm 程式設計中最重要的技巧之一,用來讓程式碼中可能的值與現實生活中有效的值完全一致,這麼一來就沒有無效資料的容身之處,也讓不可能的狀態無法在程式碼中表示出來。
type Season
= Spring
| Summer
| Autumn
| Winter
自訂型別的每個情況都可以選擇性地附加資料,不同情況也可以帶有不同型別的資料。如果所有情況都沒有附加資料,這種可辨識聯合就很像其他語言通常所稱的_列舉_(或 enum)。
type FlexibleNumber
= Integer Int
| Float Float
| Invalid
要為某個特定情況建立值,可以引用它的名稱(Spring),前提是它定義在同一個模組中,或是用 import SeasonModule exposing (Season(..)) 這種風格的語法匯入;也可以引用它的完整限定名稱(Season.Spring),前提是用 import SeasonModule exposing (Season) 這種風格的語法匯入。
integerTwo = Integer 2
invalid = FlexibleNumber.Invalid
自訂型別和 Elm 中的所有東西一樣,具有_結構相等_,也就是說,同一情況且(選填)資料相同的兩個值彼此等價。
處理自訂型別時,最推薦的做法是使用模式比對:
let describe flexibleNumber =
case flexibleNumber of
Integer i ->
"Integer: " ++ fromInt(i)
Float f ->
"Float: " ++ fromFloat(f)
Invalid ->
"Invalid"
在這個練習中,今天是情人節,你和你的另一半打算一起做些開心的事。你的另一半有很多點子,現在要請你幫這些點子評分,好從中挑出要進行的活動。
你的另一半提出了這些點子:
你有六項任務,幫助你選出情人節這天的活動。
針對另一半提出的每個點子,你要用三種選項之一來回應:yes、no 或 maybe。
定義 Approval 自訂型別,以下列三種情況來表示這些選項:Yes、No 和 Maybe。
你的另一半挑了兩間可能的餐廳:一間是韓式料理,另一間是土耳其料理。
定義 Cuisine 自訂型別,以下列兩種情況來表示這些料理:Korean 和 Turkish。
可以選的電影多到數不清,所以為了縮小範圍,你的另一半也列出了電影類型。
定義 Genre 自訂型別,用情況來表示下列類型:Crime、Horror、Romance 和 Thriller。
如前所述,你的另一半提出了五種不同的活動:玩桌遊、放鬆一下、看電影和去餐廳。
定義 Activity 自訂型別來表示這些活動類型:
BoardGame:沒有附帶資料。Chill:沒有附帶資料。Movie:附帶 Genre 資料。Restaurant:附帶 Cuisine 資料。終於,你可以開始為另一半的點子評分了。對於另一半的點子,你的感覺是:
實作一個名為 rateActivity 的函式,它接受一個 Activity 值,並根據上述的感覺回傳對應的 Approval:
rateActivity (Restaurant Turkish)
-- => Maybe