Paradygmaty programowania/Ćwiczenia 10: Programowanie funkcyjne w Haskellu I
Zadanie 1
Zdefiniuj na dwa sposoby funkcję, która do danej liczby całkowitej dodaje 5.
Zadanie 2
Przypomnijmy definicję funkcji mnożącej dwie liczby:
mnóż :: (Integer, Integer) -> Integer mnóż (x, y) = if x == 0 || y == 0 then 0 else x * y
Czy poniższy wariant byłby lepszy pod względem wykorzystania mechanizmu obliczania leniwego (tzn. który argument i kiedy nie będzie obliczany)?
mnóż (x, y) = if x == 0 then 0 else x * y
Zadanie 3
Która z poniższych funkcji nie jest jednoargumentowa?
(+2), (–7), (*5), (/2), (3/), (<1), (`div` 3), (100 `div`)
Zadanie 4
Napisz kilka wariantów „klasycznej funkcji dydaktycznej”, czyli silni. Zadbaj o obsługę błędnych argumentów. Haskell zawiera standardową funkcję error, która powoduje zerwanie obliczeń i wyświetlenie komunikatu o błędzie. Funkcja error bierze jeden argument napisowy. Zwróć uwagę, że aby wywołać funkcję z argumentem ujemnym, trzeba go ująć w nawiasy (w przeciwnym razie minus w wywołaniu np. silnia –2 zostanie uznany za operator dwuargumentowy i dostaniemy komunikat o błędzie, ale nie tym, o którym mówimy...).
Zadanie 5*
Zastanów się (ponownie...) nad obliczaniem wyrazów ciągu Fibonacciego. Z oczywistych powodów prosta funkcja, odzwierciedlająca rekurencyjną definicję, jest nieefektywna. Czy wiesz już, jak napisać lepszą?
Zadanie 6
Zapisz nową wersję funkcji rkwadrat, która wylicza pierwiastki równania kwadratowego. Nowa wersja powinna zgłaszać błąd, jeśli równanie nie ma pierwiastków rzeczywistych. Jak sądzisz, jaka jest sygnatura funkcji error?
Zadanie 7
Postawmy definicję:
para :: Num a => a -> (a, a) para x = (x, x)
Funkcję podnoszącą do kwadratu można teraz wyrazić jako złożenie powyższej funkcji tworzącej parę z mnożeniem. Czy zatem poniższa definicja jest poprawna? Jeśli nie, to co należy zmienić?
kw :: Num a => a -> a kw = (*) . para
Zadanie 8
Napisz funkcję ppd(n, x), która podnosi x do potęgi . Zwróć uwagę zarówno na efektywność, jak i na przejrzystość definicji.