Laboratorium 3. 1. Rozszerz parser wyrażeń arytmetycznych
Transkrypt
Laboratorium 3. 1. Rozszerz parser wyrażeń arytmetycznych
Laboratorium 3. 1. Rozszerz parser wyrażeń arytmetycznych prezentowany na wykładzie, tak by uwzględniał operacje odejmowania i dzielenia. Zmienione reguły gramatyki mają poniższą postać (e oznacza pusty napis): expr ::= term ('+' expr | '-' expr | e) term ::= factor ('*' term | '/' term | e) Skorzystaj z pliku źródłowego: http://www.ia.pw.edu.pl/~mszlenk/spop/parser.hs 2. Zdefiniuj klasę typów Stackable zawierającą typy, których wartości są stosami liczb całkowitych. Typ a jest instancją klasy Stackable, jeśli istnieją dla niego operacje: a) empty :: a empty zwraca pusty stos b) push :: Int -> a -> a push x s zwraca stos s z wartością x umieszczoną na szczycie c) pop :: a -> (Int, a) pop s zwraca parę (x, s’), gdzie x jest szczytową wartością stosu s , a s’ stosem po jej usunięciu (dla pustego stosu s wynik operacji jest niezdefiniowany) Następnie stwórz przykładowy własny typ danych: data Stack = ... reprezentujący takie stosy i uczyń go instancją klasy Stackable. Sprawdź poprawność implementacji obliczając wartość wyrażenia: ghci> (fst . pop $ snd . pop $ push 2 $ push 1 $ (empty :: Stack)) == 1 True Wyjaśnienie. Użyty operator $ z biblioteki standardowej jest zdefiniowany następująco: f :: (a -> b) -> a -> b f $ x = f x Operator aplikuje funkcję do jej argumentu, ale ma najniższy priorytet wśród operatorów. Pozwala dzięki temu uniknąć konieczności wpisywania dodatkowych nawiasów w złożonych wyrażeniach. 3. Napisz wersję starochińskiej gry "Nim", przyjmując poniższe zasady. Plansza gry składa się z 5 rzędów gwiazdek: 1: 2: 3: 4: 5: ***** **** *** ** * Dwóch graczy na zmianę usuwa jedną lub więcej gwiazdek z wybranego (jednego) rzędu. Wygrywa ten, który usunie ostatnią gwiazdkę lub gwiazdki z planszy. Wskazówka. Planszę można reprezentować jako listę pięciu liczb całkowitych oznaczających liczbę gwiazdek pozostałych w danych rzędzie. Np. początkowy stan planszy to lista: [5, 4, 3, 2, 1].