Az Opaque típusok egy enkapszulációs technika az Elmben.
Sokan információelrejtésnek, illetve az implementációs részletek elrejtésének is nevezik.
Gyakran használják az érvényesítés kikényszerítésére is, a Parse, dont validate mintát követve.
Például lehet egy EmailAddress opaque típusod, amely csak érvényes e-mail-címeket tartalmazhat (szemben a String-gel, amely bármit tartalmazhat).
Az egyedi típusoknak egy vagy több változatuk van, és a fordító automatikusan generál egy-egy függvényt minden változat létrehozásához, a változat nevének felhasználásával. Egyedi típust kizárólag így lehet létrehozni. A fordító ezeknek a változatoknak a destrukturálását is lehetővé teszi.
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 _'
Alapértelmezés szerint mindez a fájlon / modulon belül marad, és az exposing kulcsszóval döntjük el, mit exportálunk.
A Maybe modul közzéteszi a Maybe típust (hogy más modulok használhassák a meglévő Maybe értékeket), és közzéteszi a Nothing és Just változatokat is (hogy más modulok létrehozhassanak és destrukturálhassanak Maybe értékeket).
Ehhez a következő szintaxist használja.
A Maybe(..) rész azt mondja az Elmnek, hogy az összes változatot tegye közzé, az egyedi típus definíciójával együtt.
module Maybe exposing
( Maybe(..)
-- ...
)
Opaque típus létrehozásához egyszerűen nem exportálod a változatokat.
A Maybe típusnál ezt így teheted meg:
module Maybe exposing
( Maybe
-- ...
)
Amikor így teszel, szinte mindig kell egy másik mód is a változatok létrehozására és elérésére: egyedi függvényeket kell közzétenned. Ezek az egyedi függvények lehetővé teszik, hogy bizonyos logikát alkalmazz a változatok létrehozásakor és elérésekor. Ez elrejti a modul belső implementációs részleteit, és azt jelenti, hogy annyit változtathatsz a részleteken, amennyit csak szeretnél, amíg a közzétett függvények változatlanok maradnak. A típus létrehozásakor és használatakor pedig lehetővé teszi az invarianciák fenntartását is.
Az Opaque típusok messze leggyakoribb felhasználása az érvényesítés kikényszerítése a Parse, dont validate minta segítségével.
Ebben a mintában közzéteszel egy függvényt, amely egy nálad kevésbé strukturált / típusbiztos bemenetet kap, például egy String-et, majd ezt feldolgozod egy strukturáltabb típussá, például EmailAddress-szé, és vagy visszaadod a típust, vagy hibát adsz vissza (általában Maybe-t vagy Result-ot).
Például az alábbi kódban a külső modulok csak a parseEmailAddress függvénnyel hozhatnak létre EmailAddress típust, így amikor EmailAddress típussal dolgozol, biztos lehetsz benne, hogy érvényes.
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
-- ...