軌道
/
Elm
Elm
/
課程大綱
/
不透明型別
不透

不透明型別 在 Elm

2 個練習

關於 不透明型別

簡介

不透明型別是 Elm 中的一種封裝技巧。 有些人也稱它為資訊隱藏,也就是把實作細節藏起來。 它們也常被用來強制執行驗證,採用 Parse, dont validate 模式。 舉例來說,你可以有一個EmailAddress不透明型別,它只能包含有效的電子郵件地址(相對於String,它可以包含任何內容)。

建立不透明型別

自訂型別有一或多個變體,而編譯器會自動產生一個函式來建立每個變體,用的就是變體的名稱。 自訂型別也只能透過這種方式建立。 編譯器也允許對這些變體進行解構。

type Maybe a
    = Nothing --> Variant implies a 'Nothing' function, with type 'Maybe a', and destructuring of 'Nothing'
    | Just a  --> Variant implies a 'Just' function, with type 'a -> Maybe a', and destructuring of 'Just _'

預設情況下,這些全都是檔案或模組內部的,我們用exposing關鍵字來選擇要匯出什麼。 Maybe模組會公開Maybe型別(讓其他模組可以使用既有的Maybe值),也會公開Nothing和Just變體(讓其他模組可以建立並解構Maybe值)。 它使用以下的語法來做到這件事。 Maybe(..)的部分告訴 Elm 要公開所有的變體,以及自訂型別的定義。

module Maybe exposing
  ( Maybe(..)
  -- ...
  )

要建立不透明型別,你只要選擇不匯出變體就好。 對Maybe型別來說,你會使用以下的語法:

module Maybe exposing
  ( Maybe
  -- ...
  )

這麼做的時候,你幾乎總是得提供另一種建立及取得變體的方式,也就是公開自訂函式。 這些自訂函式讓你在建立和取得變體時能套用一些邏輯。 這麼做會把模組內部的實作細節隱藏起來,也代表只要公開的函式維持不變,你可以隨意變更實作細節。 它也讓你在建立和使用這個型別時可以維持不變量。

Parse, don't validate

不透明型別最常見的用途,大概就是用來強制執行驗證,採用 Parse, dont validate 模式。 在這個模式中,你公開一個函式,它接受的輸入結構或型別安全程度比你想要的低,例如String,然後把這個輸入解析成結構更完整的型別,例如EmailAddress,並且回傳該型別,或是回傳一個錯誤(通常是Maybe或Result)。

舉例來說,在下面的程式碼中,外部模組只能透過parseEmailAddress函式建立EmailAddress型別,所以當你在處理EmailAddress型別時,你就能確定它是有效的。

module EmailAddress exposing ( EmailAddress, parseEmailAddress, getEmailAddress )

-- The `EmailAddress` custom type has one variant, also called `EmailAddress`
-- When a custom type has one variant, it is idiomatic to use the same name for both.
type EmailAddress = 
  EmailAddress String

-- create an EmailAddress variant
parseEmailAddress: String -> Maybe EmailAddress
parseEmailAddress candidateEmailAddress =   
  if isValidEmailAddress candidateEmailAddress then
    Just (EmailAddress candidateEmailAddress)
  else
    Nothing

-- get an EmailAddress variant
getEmailAddress: EmailAddress -> String
getEmailAddress ( EmailAddress  emailAdress ) =
  emailAdress

isValidEmailAddress: String -> bool
-- ... 
透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 不透明型別

練習已鎖定

再解鎖 1 個練習,就能練習 不透明型別