# The Shape Example in Haskell

Contributed by Chris Rathman

### File: Shape.hs

```module Shape(Shape, getX, getY, setX, setY, moveTo, rMoveTo, draw)

where

-- declare method interfaces for the shape superclass
class Shape a where
getX :: a -> Int
getY :: a -> Int
setX :: a -> Int -> a
setY :: a -> Int -> a
moveTo :: a -> Int -> Int -> a
rMoveTo :: a -> Int -> Int -> a
draw :: a -> IO()```

### File: Circle.hs

```module Circle(Circle, MakeCircle, getRadius, setRadius)

where
import Shape

-- declare method interfaces for circle subclass
class Shape a => Circle a where
setRadius :: a -> Int -> a

-- define the methods for shape superclass
instance Shape CircleInstance where
getX = x
getY = y
setX a newx = a {x = newx}
setY a newy = a {y = newy}
moveTo a newx newy = a {x = newx, y = newy}
rMoveTo a deltax deltay = a {x = ((getX a) + deltax), y = ((getY a) + deltay)}
draw a =
putStrLn ('Drawing a Circle at:(' ++ (show (getX a)) ++ ',' ++ (show (getY a)) ++

-- define the methods for circle subclass
instance Circle CircleInstance where

-- declare the constructor for circle class
data CircleInstance = MakeCircle {x, y, radius :: Int}
deriving(Eq, Show)```

### File: Rectangle.hs

```module Rectangle(Rectangle, MakeRectangle, getWidth, getHeight, setWidth, setHeight)

where
import Shape

-- declare method interfaces for rectangle subclass
class Shape a => Rectangle a where
getWidth :: a -> Int
getHeight :: a -> Int
setWidth :: a -> Int -> a
setHeight :: a -> Int -> a

-- define the methods for shape superclass
instance Shape RectangleInstance where
getX = x
getY = y
setX a newx = a {x = newx}
setY a newy = a {y = newy}
moveTo a newx newy = a {x = newx, y = newy}
rMoveTo a deltax deltay = a {x = ((getX a) + deltax), y = ((getY a) + deltay)}
draw a =
putStrLn ('Drawing a Rectangle at:(' ++ (show (getX a)) ++ ',' ++ (show (getY a)) ++
'), width ' ++ (show (getWidth a)) ++ ', height ' ++ (show (getHeight a)))

-- define the methods for rectangle subclass
instance Rectangle RectangleInstance where
getWidth = width
getHeight = height
setWidth a newwidth = a {width = newwidth}
setHeight a newheight = a {height = newheight}

-- declare the constructor for rectangle class
data RectangleInstance = MakeRectangle {x, y, width, height :: Int}
deriving(Eq, Show)```

### File: Polymorph.hs

```module Polymorph(main)

where
import Shape
import Circle
import Rectangle

main =
do
-- handle the shapes polymorphically
drawloop scribble1
drawloop scribble2

-- handle rectangle specific instance
draw arectangle
draw (Rectangle.setWidth arectangle 30)

where
-- create lists containing instances of each shape
scribble1 = (MakeCircle 15 25 8):[]
scribble2 = (MakeRectangle 10 20 5 6):[]

-- create a rectangle instance
arectangle = (MakeRectangle 0 0 15 15)

-- iterate through the list of shapes and draw
drawloop [] = return True
drawloop (x:xs) =
do
draw x
draw shapeMoved
drawloop xs
where
shapeMoved = (Shape.rMoveTo x 100 100)```

### File: Polymorph.prj

```Shape.hs
Circle.hs
Rectangle.hs
Polymorph.hs```

## Output

```Drawing a Circle at:(15,25), radius 8
Drawing a Circle at:(115,125), radius 8
Drawing a Rectangle at:(10,20), width 5, height 6
Drawing a Rectangle at:(110,120), width 5, height 6
Drawing a Rectangle at:(0,0), width 15, height 15
Drawing a Rectangle at:(0,0), width 30, height 15```