-- Time-stamp: -- -- Simple Haskell functions demonstrating basics of Haskell. -- Used for the course 12.4PL1 "Language and Design", term 1, 2001/02. -- -- The structure in this module corresponds to the structure in the -- lecture. -- -- Use the ghci as Haskell interpreter. -- It's available from: /net/azdak/dsg/local/i386-unknown-linux/bin -- Documentation: http://haskell.cs.yale.edu/ghc/documentation.html --------------------------------------------------------------------------- module Demos_1 where -- I. Algebraic data-types data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Read,Show,Eq,Ord) data MyList alpha = Nil | alpha :^ (MyList alpha) -- Pattern matching over this new data type is very useful: next Mon = Tue next Tue = Wed next Wed = Thu next Thu = Fri next Fri = Sat next Sat = Sun next Sun = Mon -- Parametric polymorphism means that you can define functions that work for any -- instance of \texttt{alpha}: my_length :: MyList alpha -> Int my_length Nil = 0 my_length (x:^xs) = 1+(my_length xs) -- Pattern matching sqs1 [] = [] sqs1 (h:t) = h*h : sqs1 t sqs2 xs = if (null xs) then [] else let h = head xs t = tail xs in h*h : sqs2 t -- Guarded patterns more0 [] = 0 more0 (h:t) | h>0 = 1+more0 t | otherwise = more0 t -- squares-even as a list comprehension sqs1_even xs = [x*x | x <- xs, even x] --------------------------------------------------------------------------- -- II. Higher-order functions -- The predefined higher-order function map applies a function to all -- elements of a list, i.e. map f [1,2,3] = [f 1, f 2, f 3] -- squares-even with higher-order functions sqs2_even = map (\ x -> x*x) . filter even -- using a map sqs4 xs = map square xs where square x = x*x -- using a map and an anonymous function sqs5 xs = map (\ x -> x*x) xs -- using a map and a section sqs6 xs = map (^2) xs -- same as above, but shorter sqs7 = map (^2) --------------------------------------------------------------------------- -- IV. Lazy Evaluation -- this functions generates an infinite list of values, starting with x -- the same as typing: [x..] in the interpreter my_enumFrom :: Int -> [Int] my_enumFrom n = n:(my_enumFrom (n+1)) -- Test this by trying e.g. -- > (my_enumFrom 1) !! 2 -- or -- > take 10 (my_enumFrom 1) my_enumFromTo :: Int -> Int -> [Int] my_enumFromTo m n | m<=n = m:(my_enumFromTo (m+1) n) | otherwise = [] -- Test this by trying e.g. -- > (my_enumFromTo 1 10) !! 2 -- or -- > take 10 (my_enumFromTo 1 10) -- the following variants of the above functions demonstrate the -- use of type classes and overloading in Haskell my_enumFrom' :: (Enum a) => a -> [a] my_enumFrom' n = n:(my_enumFrom' (succ n)) -- this is a more general version using type classes and overloading -- so that we can use the function on many different types, namely -- all types that have a '<' function (therefore we need Ord) and -- all types that have a 'succ' function (therefore we need Enum) my_enumFromTo' :: (Ord a, Enum a) => a -> a -> [a] my_enumFromTo' m n | m<=n = m:(my_enumFromTo' (succ m) n) | otherwise = []