{-# LANGUAGE FlexibleContexts, FlexibleInstances, OverlappingInstances #-}
--data Person = Person String Integer String
data Person = Person
{ name :: String
, alter :: Integer
, adresse :: String
} deriving Show
fun1 :: Eq a => [a] -> Bool
fun1 xs = (xs == [])
fun2 :: (a->[Char]->[Char]) -> t -> [a] -> [Char]
fun2 f a = foldr f "a"
fun3 :: ((d->e)->a->(d->e)) -> (d->e) -> [a] -> d -> e
fun3 f a xs c = foldl f a xs c
--fun4 f xs = map f xs xs
fun5 :: (Ord a, Enum a, Num c) => a -> a -> c -> (a, c)
fun5 a b c = (maximum [a..b], 3 * c)
fun6 :: (Enum a, Enum b, Enum c) => a -> b -> c
fun6 x y = succ (toEnum (last [fromEnum x..fromEnum y]))
fun7 :: (Show ([Char]->a)) => ([Char] -> a) -> ([Char] -> a)
fun7 x = if show x /= [] then x else error
data Exp t = Const Integer
| Var t
| Sum (Exp t) (Exp t)
| Less (Exp t) (Exp t)
| IfThenElse (Exp t) (Exp t) (Exp t)
type Env t = t -> Integer
eval :: Env t -> Exp t -> Integer
eval env (Const i) = i
eval env (Var v) = env v
eval env (Sum a b) = eval env a + eval env b
eval env (Less a b)
| eval env a < eval env b = 1
| otherwise = 0
eval env (IfThenElse i t e)
| eval env i /= 0 = eval env t
| otherwise = eval env e
envTest 'c' = 7
--myShow :: String -> String
--myShow a = a
--
--myShow :: Show a => a -> String
--myShow a = show a
instance Show (Exp String) where
show (Const i) = show i
show (Var v) = v
show (Sum a b) = "(" ++ show a ++ " + " ++ show b ++ ")"
show (Less a b) = "(" ++ show a ++ " < " ++ show b ++ ")"
instance (Show t) => Show (Exp t) where
show (Const i) = show i
show (Var v) = show v
show (Sum a b) = "(" ++ show a ++ " + " ++ show b ++ ")"
show (Less a b) = "(" ++ show a ++ " < " ++ show b ++ ")"
cfold' (Sum (Const a) (Const b)) = Const (a+b)
cfold' (Less (Const a) (Const b))
| a < b = Const 1
| otherwise = Const 0
cfold' x = x
cfold :: Exp t -> Exp t
cfold (Sum x y) = cfold' $ Sum (cfold x) (cfold y)
cfold (Less x y) = cfold' $ Less (cfold x) (cfold y)
cfold x = x
type Church t = (t -> t) -> t -> t
int2church :: Int -> Church t
int2church 0 = \s z -> z
int2church n = \s z -> s (int2church (n-1) s z)
--int2church n = \s z -> foldr (\a b -> a b) z (take n $ repeat s)
--int2church n = \s z -> iterate s z !! n
church2int c = c (+1) 0