{-# 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