module Test where -- Various ways of defining functions len1::[a] -> Integer len1 [] = 0 len1 (x:xs) = 1 + len1 xs len2::[a] -> Integer len2 = \x -> if (null x) then 0 else 1 + (len2 (tail x)) l1 = (len1 [1, 2, 3]) l2 = (len2 [1, 2, 3]) -- Currying add::Integer -> Integer -> Integer add x y = x + y add3::Integer -> Integer add3 = add 3 z::Integer z = add3 4 -- Lazy evaluation omit x = 0 v = omit (1/0) showv = putStr (show v) --- Misc features -- Higher order functions square x = x*x squareList l = map square l productOfList l = foldl (*) 1 l fact x = productOfList [1..x] -- List comprehensions s1 = [1..5] s2 = [ odd x | x <- [1..5]] s3 = [ x*y | x <- [1..3], y <- [1, 10, 100]] s4 = [ x:y:[] | x <- "abcd", y <- "abcd", x < y] -- Guards filterGreaterThan :: Int -> [Int] -> [Int] filterGreaterThan n l = case l of [] -> [] x:xs | x <= n -> x:(filterGreaterThan n xs) | otherwise -> (filterGreaterThan n xs) -- parametric polymorphism identity :: a -> a identity x = x len3 :: [a] -> Int len3 [] = 0 len3 (x:xs) = 1 + len3 xs rest :: [a] -> [a] rest [] = [] rest (x:xs) = xs eval::(a -> b) -> a -> b eval f x = f x -- constraints not_equal:: Eq a => a -> a -> Bool not_equal x y = if (x == y) then False else True -- data type definitions -- type classes -- deriving, instance declarations data Useless = Useless data Useful = Useful deriving (Eq, Show) instance Eq Useless where (==) a b = False instance Show Useless where show a = "This is uselss object" -- One function signature only in one type class class Fooable a where foo :: a -> a class AnotherFunClass b where bar :: b -> b -- foo :: b -> b -> String -- Instance declarations are not generated automatically -- from instance declarations of "inherited" type classes class A a where class A a => B a where instance A Integer where instance B Integer where -- Functional dependencies class Container a b | a -> b where toList :: a -> [b] fromList :: [b] -> a instance Container [a] a where toList = id fromList = id instance Container Int Int where toList x = [x] fromList [x] = x fromList _ = error "only singleton list accepted" -- instance Container Int String where -- toList x = [show x] -- fromList [x] = read x -- fromList _ = error "only singleton list accepted" -- More than one constraint on a single type parameter show_min :: (Ord a, Show a) => a -> a -> String show_min x y = show (min x y)