Rozwiązanie
Stworzyć własny typ danych, który reprezentuje kolory
data RGB = RGB (Int, Int, Int)
data Kanały = Kanały { czerwony::Int, zielony::Int, niebieski::Int }
-- bez stylu rekordowego: data Kanały = Kanały Int Int Int
data Kolor = Czerwony | Żółty | Zielony | Cyjan |
Niebieski | Fuksja | Biały | Czarny
Rozwiązanie
Zaimplementować operację dodawania z klasy Num
dla tego nowego typu przechowującego kolory
x +% y = max 255 (x + y)
infixl 6 +%
instance Num RGB where
(RGB (r1, g1, b1)) + (RGB (r2, g2, b2)) =
RGB (r1 +% r2, g1 +% g2, b1 +% b2)
instance Num Kanały where
p + q = Kanały
(czerwony p +% czerwony q)
(zielony p +% zielony q)
(niebieski p +% niebieski q)
instance Num Kolor where
Czerowny + Zielony = Żółty
Zielony + Czerowny = Żółty
Zielony + Niebieski = Cyjan
Niebieski + Zielony = Cyjan
Czerwony + Niebieski = Fuksja
Niebieski + Czerwony = Fuksja
_ + _ = Czarny
Rozwiązanie
Mając typ danych data Drzewo a = Nic | Węzeł a (Drzewo a) (Drzewo a)
zaimplementować dla niego instancję funktora
Właściwości funktorów:
fmap id == id
fmap (f . g) == fmap f . fmap g
data Drzewo a = Nic | Węzeł a (Drzewo a) (Drzewo a)
instance Functor Drzewo where
fmap _ Nic = Nic
fmap f (Węzeł x left right) =
Węzeł (f x) (fmap f left) (fmap f right)
Rozwiązanie - przypadek użycia
znajdź ident = maybe Niezarejestrowany Znany . lookup ident
znajdź baza ident = maybe Niezarejestrowany Znany $ lookup ident baza
Rozwiązanie
Bazując na poprzedniej implementacji, zapisać dla typu Drzewo
instancję aplikatora
Właściwości aplikatorów:
pure id <*> v == v
pure (.) <*> u <*> v <*> w == u <*> (v <*> w)
pure f <*> pure x == pure (f x)
u <*> pure y == pure ($ y) <*> u
instance Applicative Drzewo where
pure x = Węzeł x Nic Nic
Nic <*> _ = Nic
_ <*> Nic = Nic
(Węzeł f Nic Nic) <*> (Węzeł x x1 x2) =
Węzeł (f x) (f <$> x1) (f <$> x2)
(Węzeł f f1 f2) <*> (Węzeł x x1 x2) =
Węzeł (f x) (f1 <*> x1) (f2 <*> x2)