Szukaj…


Podstawowe użycie

Gdy rozszerzenie GADTs jest włączone, oprócz zwykłych deklaracji danych można również zadeklarować uogólnione algebraiczne typy danych w następujący sposób:

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

Deklaracja GADT wyraźnie wymienia typy wszystkich konstruktorów, których typ danych ma. W przeciwieństwie do zwykłych deklaracji typów danych, typem konstruktora może być dowolna funkcja N-ary (w tym zerowa), która ostatecznie skutkuje typem danych zastosowanym do niektórych argumentów.

W tym przypadku zadeklarowaliśmy, że typ DataType ma trzy konstruktory: Constr1 , Constr2 i Constr3 .

Konstruktor Constr1 nie różni się od deklarowanego przy użyciu zwykłej deklaracji data DataType a = Constr1 Int a (Foo a) | ... : data DataType a = Constr1 Int a (Foo a) | ...

Constr2 wymaga jednak, aby a miało instancję Show , a więc przy użyciu konstruktora instancja musiałaby istnieć. Z drugiej strony, gdy dopasowuje się do niego wzorzec, wchodzi w zakres fakt, że a jest instancją Show , więc możesz napisać:

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

Zauważ, że Show a ograniczenie nie pojawia się w typie funkcji i jest widoczne tylko w kodzie po prawej stronie -> .

Constr3 ma typ Constr3 DataType Int , co oznacza, że ilekroć wartość typu Constr3 DataType a jest Constr3 , wiadomo, że a ~ Int . Te informacje również można odzyskać za pomocą dopasowania wzorca.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow