Sök…


Grundläggande användning

När GADTs tillägget är aktiverat kan du, förutom vanliga datadeklarationer, också deklara generaliserade algebraiska datatyper enligt följande:

data DataType a where
    Constr1 :: Int -> a -> Foo a -> DataType a
    Constr2 :: Show a => a -> DataType a
    Constr3 :: DataType Int

En GADT-deklaration visar de typer av alla konstruktörer som en datatyp har uttryckligen. Till skillnad från vanliga datatypdeklarationer kan typen av en konstruktör vara vilken som helst N-ary-funktion (inklusive nullary) -funktion som slutligen resulterar i datatypen som tillämpas på vissa argument.

I det här fallet har vi förklarat att typen DataType har tre konstruktörer: Constr1 , Constr2 och Constr3 .

Constr1 konstruktören skiljer sig inte från en deklarerad med en vanlig data DataType a = Constr1 Int a (Foo a) | ... : data DataType a = Constr1 Int a (Foo a) | ...

Constr2 kräver emellertid att a har en instans av Show , och så när konstruktorn används skulle instansen behöva existera. Å andra sidan, när mönstermatchning på det, kommer det faktum att a är en instans av Show i omfattning, så du kan skriva:

foo :: DataType a -> String
foo val = case val of
    Constr2 x -> show x
    ...

Observera att Show a begränsning inte visas i funktionstypen och endast syns i koden till höger om -> .

Constr3 har typen DataType Int , vilket innebär att när ett värde av typen DataType a är en Constr3 , är det känt att a ~ Int . Denna information kan också återvinnas med en mönstermatchning.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow