{-# LANGUAGE RankNTypes #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} -- polymorphe funktion calcLength :: [a] -> Int calcLength [] = 0 calcLength (_:xs) = 1 + calcLength xs -- polymorphe funktion foo :: (a -> a) -> (Char, Bool) -- geht das? foo f = (f 'X', f True) foo = undefined -- polymorphe argumente (Higher Rank Types) bar :: (forall a. a -> a) -> (Char,Bool) bar f = (f 'X', f True) type PersName = String type PersMatrNr = String data Person = Student PersName PersMatrNr | Assi PersName | Prof PersName deriving Show -- Eq-class implementieren instance Eq Person where (==) (Student n1 m1) (Student n2 m2) = (n1 == n2) && (m1 == m2) (==) (Assi n1) (Assi n2) = n1 == n2 (==) (Prof n1) (Prof n2) = n1 == n2 (==) _ _ = False ex1 = Prof "Schmidt" `comp` Student "Meder" "xxx" {- Eq - grobe Analogie in Java Als Vertrag: ist auf Gleichheit testbar interface Equalable // kein gemeinsames Wurzel-"Object" in Haskell! { public boolean "==" (A a, A b); } Als Abstr Class: Vordefinierte Funktionen abstract class Equalable { public boolean "!=" (A a, A b) = !(a == b) } -} -- constraints: class (Show t, Eq t) => HumanReadableCompare t where comp :: t -> t -> (Bool, String) -- ClassImpl instance HumanReadableCompare Int where comp a b | a == b = (True, "Equals") | otherwise = (False, (show a) ++ " differs from " ++ (show b)) instance HumanReadableCompare Person where comp p1 p2 | p1 == p2 = (True, "Equals") | otherwise = (False, (show p1) ++ " differs from " ++ (show p2)) -- class Collection c where -- class Collection c e where class Eq e => Collection c e where insert :: c -> e -> c member :: c -> e -> Bool -- Eq für member -- FlexibleInstances ! instance Eq e => Collection [e] e where insert = flip (:) member = flip elem ex2 :: [Int] -> Int -> [Int] ex2 cs x = cs `insert` x