--show :: a -> String --show x = data Pair a = P a a instance Show a => Show (Pair a) where show (P x y) = "<" ++ show x ++ ";" ++ show y ++ ">" data NestedList a = Atom a | List [NestedList a] deriving Show -- (1 2 (3 4) 5) -- List [Atom 1, Atom 2, List [Atom 3, Atom 4], Atom 5] {-- class where | expresie de tip v instance [] where --} class Invertible a where -- "a aderă la clasa Invertible" invert :: a -> a invert x = id x instance Invertible a => Invertible [a] where invert lista = reverse $ map invert lista instance Invertible a => Invertible (Pair a) where invert (P x y) = P y x instance Invertible a => Invertible (NestedList a) where invert (Atom x) = Atom x invert (List nl) = List $ invert nl instance Invertible Bool instance Invertible Integer -- variabila de tip din definiția clasei nu este neapărat un tip -- ci poate fi un constructor de tip class Container t where -- "dacă construiesc un tip aplicând constructorul de tip t peste un tip a" contents :: t a -> [a] instance Container Pair where contents (P x y) = [x, y] instance Container NestedList where contents (Atom x) = [x] -- lista este listă Haskell contents (List lista) = concat $ map contents lista -- constructorul de *tip* pentru tipul listă -- v instance Container [] where contents lista = lista {- f4 :: a -> b -> c -> d din x == y : a = b și Eq a din x > y: a = b și Ord a din valoarea întoarsă: a = d = b = c f4 :: (Eq a, Ord a) => a -> a -> a -> a f4 :: Ord a => a -> a -> a -> a -} f4 x y z = if x == y then z else if x > y then x else y {- f5 :: a -> b -> c din contents x (-> [m]): Container t și a = t m din (==): Eq m din invert y, invert x: Invertible b, Invertible a din valoarea întoarsă de funcție: a = b = c = t m f5 :: (Container t, Eq m, Invertible (t m)) => t m -> t m -> t m -} f5 x y = if contents x == [] then invert y else invert x {- f2 :: a -> b -> c din invert x, invert y: Invertible a. Invertible b, din ==: a = b, Eq a din contents x, contents y: a = b = t m Container t din valoarea întoarsă: c = [m] f2 :: (Invertible (t m), Container t, Eq (t m)) => t m -> t m -> [m] -} f2 x y = if (invert x) == (invert y) then contents x else contents y {- f3 :: a -> b -> c din head x, head y, >: a = b = [m], Ord m din invert x: Invertible [m] din (++): a = [m] din (-): Num m tipul întors: c = [m] f3 :: (Invertible [m], Ord m, Num m) => [m] -> [m] -> [m] f3 :: (Invertible m, Ord m, Num m) => [m] -> [m] -> [m] -} f3 x y = if head x > head y then (invert x) ++ (invert y) else [head y - head x]