w Haskell mamy trzy drogi do zdefiniowania nowego typu, stosując trzy różne słowa kluczowe, typu, newtype i dane.
W twoim przykładzie jest to słowo kluczowe data, skupmy się nieco na nim.
Lepiej zacząć od najprostszych jeden pochodzący z kodem
data E = A | B
Tutaj mamy zdefiniować nowy typ E, która może przyjmować tylko dwie tryb lub państwowej lub wartość.
Typ taki jak ten nazywamy typem sumy . Jak możemy go użyć?
Głównie z pasującym wzorcem .
useE :: E -> String
useE A = "This is A"
useE B = "This is B"
Teraz bardziej złożona deklaracja danych z kodu.
data Q = Q0 | Q1 | Q2 deriving (Eq, Enum, Bounded)
Ponownie jak już wspomniano wcześniej, że mają typu suma które określają nowego typu Q, przyjmowane trzy wartości, Q0, Q1 lub Q2. Ale mamy klauzulę wywodzącą , która mówi kompilatorowi, że ten nowy typ implementuje metodę (lub funkcję) wyprowadzającą (lub odziedziczoną) z Eq, Enum, Bounded class. Co to znaczy?
Spójrzmy na funkcję.
Wyobraź sobie, że chcesz powiązać liczbę dla każdej wartości Q, w jaki sposób możemy to wykonać?
enumQ :: Q -> Int
enumQ x = fromEnum x
Jeśli chcesz więcej wgląd o tej konkretnej funkcjonalności dostarczenie przez wynikających klauzulę, przeczytaj zasobów, które zostały wskazane i spróbuj : info Enum pod ghci. Zauważ, że poprzedni typ mógł również pochodzić z tej samej klasy. Ponieważ te typy są w pełni opisane jako suma przeliczalnego zestawu wartości (dyskryminowanego przez |), lepiej rozumiemy, dlaczego nazywamy je sumą typu sumą typu.
Wreszcie najtrudniejsza deklaracja danych.
data DFA q o = DFA (q -> o -> q) q [q]
data NFA q o = NFA (q -> o -> [q]) [q] [q]
Jeśli fakt, że są prawie takie same dane definicja wtedy pójdę koryta pierwszy i niech ci analiz drugi jako ćwiczenie.
data DFA q o = DFA (q -> o -> q) q [q]
Tym razem musimy mówić o konstruktora danych i typ konstruktora.
- Z lewej strony równości istnieje konstruktor dane, do budowanych danych i nadać mu nazwę. Po tej stronie mamy wymagany parametr użyty do zbudowania tych nowych danych.
- Po prawej stronie równości znajduje się konstruktor typu, do , który zbudował ten nowy typ. Po tej stronie mamy wyraźne hydraulikowanie , które pokazuje czytelnikowi, jak ten nowy typ (dane) jest zbudowany przy użyciu istniejącego typu.
Teraz mając na uwadze, że po to typ,
- [x] ::: Rodzaj reprezentujący polimorficzny listy, przykład [Int] => Lista Int
- x ::: podstawowy typ, jeden z istniejącą (int, char, string ...)
- x -> y ::: Rodzaj które definiują funkcję zrobieniu typu x do prod ui a typ: y.
- x -> y -> z ::: Typ definiujący funkcję typu x i y, aby utworzyć typ z. Który może być widokiem jako funkcją przyjmującą inną funkcję typu (x-> y) i tworzącą typ z. To nazywamy funkcją wysokiego rzędu .
Następnie nasze zgłoszenie danych znajdująca się w tym kontekście to konstruktor danych, paszy przez dwa parametru typu, q i O i w rezultacie powrót nowy typ jako iloczyn funkcja wyższego rzędu to typ podstawowy i typ listy. Co tłumaczy, dlaczego nazywamy to produktem typu :.
Powinno wystarczyć, teraz, wnioskowanie przez siebie, aby odpowiedzieć na pytanie: co robi n1?
Powodzenia.
[Poznaj Haskella dla wielkiego dobra] (http://learnyouahaskell.com/) jest prawdopodobnie dobrym miejscem do rozpoczęcia. Musisz być w stanie przeczytać i zrozumieć co najmniej podstawowe sygnatury typu Haskella, aby zacząć robić postępy z zadaniem. – shang
Po drugie, możesz przeczytać artykuły z Wikipedii na temat [DFAs] (http://en.wikipedia.org/wiki/Deterministic_finite_automaton) i [NFAs] (http://en.wikipedia.org/wiki/Nondeterministic_finite_automata). – shang