
	Haskell: The Craft of Functional Programming
	Simon Thompson
	(c) Addison-Wesley, 1999.

	Chapter 5


>	module Chapter5 where

>	import Prelude hiding (id)

Data types: tuples and lists
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Introducing tuples, lists and strings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>	type ShopItem = (String,Int)
>	type Basket   = [ShopItem]

>	basket1 :: Basket
>	basket1 = [ ("Salt: 1kg",139) , ("Plain crisps",25) , ("Gin: 1lt",1099) ]

>       basket2 :: Basket
>       basket2 = []

>       basket3 :: Basket
>       basket3 = [ ("Salt: 1kg",139) , ("Plain crisps",25) , ("Plain crisps",25) ]


Tuple types
^^^^^^^^^^^

Minimum and maximum of two integers.

>	minAndMax :: Int -> Int -> (Int,Int)
>	minAndMax x y
>	  | x>=y        = (y,x)
>	  | otherwise   = (x,y)

Adding a pair of intgers.

>	addPair :: (Int,Int) -> Int
>	addPair (x,y) = x+y

Shifting around the structure of an ((Int,Int),Int).

>	shift :: ((Int,Int),Int) -> (Int,(Int,Int))
>	shift ((x,y),z) = (x,(y,z))

Selecting parts of a tuple

>	name  :: ShopItem -> String
>	price :: ShopItem -> Int

>	name  (n,p) = n
>	price (n,p) = p

Adding a pair using the built-in selectors, fst and snd.

>	addPair' :: (Int,Int) -> Int
>	addPair' p = fst p + snd p

Fibonacci numbers: an efficient function, fastFib.

>	fibStep :: (Int,Int) -> (Int,Int)
>	fibStep (u,v) = (v,u+v)

>	fibPair :: Int -> (Int,Int)
>	fibPair n
>	  | n==0        = (0,1)
>	  | otherwise   = fibStep (fibPair (n-1))

>	fastFib :: Int -> Int
>	fastFib = fst . fibPair

>	fibTwoStep :: Int -> Int -> (Int,Int)
>	fibTwoStep x y = (y,x+y)



Lists in Haskell
^^^^^^^^^^^^^^^^

Various examples of lists

>	list1 :: [Int]
>	list1 = [1,2,3,4,1,4]

>       list2 :: [Bool]
>       list2 = [True]

>	list3 :: String
>       list3 = ['a','a','b']

>	list4 :: String
>	list4 = "aab"

>	list5 :: [ Int -> Int ]
>	list5 = [fastFib,fastFib]

>	list6  :: [ [Int] ]
>	list6 = [[12,2],[2,12],[]]

>	list7 :: [Int]
>	list7 = [2 .. 7]

>	list8 :: [Float]
>	list8 = [3.1 .. 7.0]

>	list9 :: String
>	list9 = ['a' .. 'm']

>	list10 :: [Int]
>	list10 = [7,6 .. 3]

>	list11 :: [Float]
>	list11 = [0.0,0.3 .. 1.0]

>	list12 :: String
>	list12 = ['a','c' .. 'n']


List comprehensions
^^^^^^^^^^^^^^^^^^^
Examples of list comprehensions

>	ex :: [Int]
>	ex = [2,4,7]

>	comp1 :: [Int]
>	comp1 = [ 2*n | n<-ex]

>	comp2 :: [Bool]
>	comp2 = [ isEven n | n<-ex ]

>	isEven :: Int -> Bool
>	isEven n = (n `mod` 2 == 0)

>	comp3 :: [Int]
>	comp3 = [ 2*n | n <- ex , isEven n , n>3 ]

Add all the pairs in a list of pairs.

>	addPairs :: [(Int,Int)] -> [Int]
>	addPairs pairList = [ m+n | (m,n) <- pairList ]

Return only the sums of pairs which are increasing.

>	addOrdPairs :: [(Int,Int)] -> [Int]
>	addOrdPairs pairList = [ m+n | (m,n) <- pairList , m<n ]

Return only the digits in a String.

>	digits :: String -> String
>	digits st = [ ch | ch<-st , isDigit ch ] 

Are all the integers in a list even? or odd?

>	allEven, allOdd :: [Int] -> Bool
>	allEven xs = (xs == [x | x<-xs, isEven x])
>	allOdd xs  = ([] == [x | x<-xs, isEven x])


A library database
^^^^^^^^^^^^^^^^^^

Types

>	type Person = String
>	type Book   = String

>	type Database = [ (Person , Book) ]

An example database.

>	exampleBase :: Database
>	exampleBase 
>	  = [ ("Alice" , "Tintin")  , ("Anna" , "Little Women") ,
>	      ("Alice" , "Asterix") , ("Rory" , "Tintin") ]

The books borrowed by a particular person in the given database.

>	books       :: Database -> Person -> [Book]
>	books dBase findPerson
>	  = [ book | (person,book) <- dBase , person==findPerson ]

Making a loan is done by adding a pair to the database.

>	makeLoan   :: Database -> Person -> Book -> Database
>	makeLoan dBase pers bk = [ (pers,bk) ] ++ dBase

To return a loan.

>	returnLoan   :: Database -> Person -> Book -> Database
>	returnLoan dBase pers bk
>	  = [ pair | pair <- dBase , pair /= (pers,bk) ]

Testing the database.

test1 :: Bool
test1 = borrowed exampleBase "Asterix"

>	test2 :: Database
>	test2 = makeLoan exampleBase "Alice" "Rotten Romans"


Generic functions: polymorphism
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
The polymorphic identity function.

>	id :: a -> a
>	id x = x

A mystery function.

>	mystery :: (Bool,a) -> Char
>	mystery (x,y) = if x then 'c' else 'd'


The String type
^^^^^^^^^^^^^^^

Example strings

>	str1, str2, str3, str4, str5 :: String

>	str1 = "baboon"
>	str2 = ""
>	str3 = "\99a\116"
>	str4 = "gorilla\nhippo\nibex"
>	str5 = "1\t23\t456"

>	pstr1, pstr2, pstr3, pstr4, pstr5 :: IO ()

>	pstr1 = putStr str1
>	pstr2 = putStr str2
>	pstr3 = putStr str3
>	pstr4 = putStr str4
>	pstr5 = putStr str5


