Session 27: Haskell introduction, cont'd

Today we complete Chapter 5 (except for the discussion of functors starting in the last two paragraphs of page 26 through the beginning of the paragraph beginning ``A Different Perspective'') from Hudak, Peterson, and Fasel's A Gentle Introduction to Haskell 98. Here are the specific examples covered in class.

-- illustrates definition of a type class
class Figure2D a where
	area :: a -> Integer
	perimeter :: a -> Integer

-- here's a function that operates over types lying within this class
scaleArea :: Figure2D a => a -> Integer -> Integer
scaleArea figure factor = factor * factor * area figure

-- here's the definition of a type in the class
data Rectangle = Rect Integer Integer

instance Figure2D Rectangle where
	area (Rect w h) = w * h
	perimeter (Rect w h) = 2 * (w + h)

-- we can define other types lying in the same class
data Expansion a = Expand a Integer

instance (Figure2D a) => Figure2D (Expansion a) where
	area (Expand shape factor) = factor * factor * area shape
	perimeter (Expand shape factor) = factor * perimeter shape

-- we can also define new classes that extend the existing class.
-- Based on the following definition, every Figure3D must be a Figure2D
-- also, and so it must have area and perimeter functions.
class (Figure2D a) => Figure3D a where
	volume :: a -> Integer

-- we can define an existing type to lie within a new class
instance (Figure3D a) => Figure3D (Expansion a) where
	volume (Expand shape factor) = factor * factor * factor * volume shape

-- and of course we can define new types lying within the class
data Prism surface = Raise surface Integer

instance (Figure2D surface) => Figure2D (Prism surface) where
	area (Raise surface depth) = 2 * area surface
		+ depth * perimeter surface
	perimeter (Raise surface depth) = 2 * perimeter surface

instance (Figure2D surface) => Figure3D (Prism surface) where
	volume (Raise surface depth) = area surface * depth