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

	Chapter 12


>	module Chapter12 where

Overloading and type classes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Why overloading?
^^^^^^^^^^^^^^^^

Testing for membership of a Boolean list.

>	elemBool :: Bool -> [Bool] -> Bool

>	elemBool x [] = False
>	elemBool x (y:ys)
>	  = (x == y) || elemBool x ys

Testing for membership of a general list, with the equality function as a
parameter.

>	elemGen :: (a -> a -> Bool) -> a -> [a] -> Bool

>	elemGen eqFun x [] = False
>	elemGen eqFun x (y:ys)
>	  = (eqFun x y) || elemGen eqFun x ys


Introducing classes
^^^^^^^^^^^^^^^^^^^

Definitions of classes cannot be hidden, so the definitions etc. here are not
executable.

class Eq a where
  (==) :: a -> a -> Bool

Functions which use equality
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Testing for three values equal: more general than Int -> Int -> Int -> Bool.

>	allEqual :: Eq a => a -> a -> a -> Bool
>	allEqual m n p = (m==n) && (n==p)

elem :: Eq a => a -> [a] -> Bool
books :: Eq a => [ (a,b) ] -> a -> [b]

It is easier to see this typing if you remane books lookupFirst:

>	lookupFirst :: Eq a => [ (a,b) ] -> a -> [b]

>	lookupFirst ws x 
>	  = [ z | (y,z) <- ws , y==x ]

borrowed    :: Eq b => [ (a,b) ] -> b -> Bool
numBorrowed :: Eq a => [ (a,b) ] -> a -> Int


Signatures and Instances
^^^^^^^^^^^^^^^^^^^^^^^^

The Visible class:

>	class Visible a where
>	  toString :: a -> String
>	  size     :: a -> Int

A type is made a member or instance of a class by defining
the signature functions for the type. For example,

instance Eq Bool where
  True  == True  = True
  False == False = True
  _     == _     = False

Declaring examples of the Visible class

>	instance Visible Char where
>	  toString ch  = [ch]
>	  size _       = 1

>	instance Visible Bool where
>	  toString True  = "True"
>	  toString False = "False"
>	  size _         = 1

An instance declaration with a context.

>	instance Visible a => Visible [a] where
>	  toString = concat . map toString  
>	  size     = foldr (+) 1 . map size  


Default definitions
^^^^^^^^^^^^^^^^^^^

To return to our example of equality, the Haskell equality class is in fact
defined by

class Eq a where
  (==), (/=) :: a -> a -> Bool
  x /= y     = not (x==y)
  x == y     = not (x/=y)


Derived classes
^^^^^^^^^^^^^^^

Ordering is built on Eq.

class Eq a => Ord a where
  (<), (<=), (>), (>=) :: a -> a -> Bool
  max, min             :: a -> a -> a
  compare              :: a -> a -> Ordering


This is the same definition as in Chapter7, but now with an overloaded type.

>	iSort :: Ord a => [a] -> [a]

>	iSort []	= []
>	iSort (x:xs) = ins x (iSort xs)

To insert an element at the right place into a sorted list.

>	ins :: Ord a => a -> [a] -> [a]

>	ins x []    = [x]
>	ins x (y:ys)
>	  | x <= y	= x:(y:ys)
>	  | otherwise	= y : ins x ys


Multiple constraints
^^^^^^^^^^^^^^^^^^^^

Sorting visible objects ...

>	vSort :: (Ord a,Visible a) => [a] -> String

>	vSort = toString . iSort 

Similarly, 

>	vLookupFirst :: (Eq a,Visible b) => [(a,b)] -> a -> String

>	vLookupFirst xs x = toString (lookupFirst xs x)

Multiple constraints can occur in an instance declaration, such as

instance (Eq a,Eq b) => Eq (a,b) where
  (x,y) == (z,w)  =  x==z && y==w

Multiple constraints can also occur in the definition of a class,

>	class (Ord a,Visible a) => OrdVis a

Can then give vSort the type:

	vSort :: OrdVis a => [a] -> String

A tour of the built-in Haskell classes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For details of the code here, please see the standard Prelude and Libraries.


Types and Classes
^^^^^^^^^^^^^^^^^

The code in this section is not legal Haskell.

To evaluate the type of concat . map show, type

	:type concat . map show

to the Hugs prompt.

