(* ---------------------------------------------------------------------- *)
(* Pairs *)
(* Problem: represent rectangles, with operations
- compute the area
- compute the permiter
- test if square
- compute a new rectangle with double the width *)
(* The first step is to figure out how to represent the information as data.
A student suggested a representation as (width,height),
which would be good except for operations on more than one rectangle,
like checking for overlap, and for operations like
displaying it on the screen.
Instead, we'll use coordinates. In general we'd need all four corners,
but we'll assume that the rectangle is oriented on the coordinate system,
so it's enough to have the lower-left and upper-right corners
_____________________b
| |
| |
| |
| |
a____________________|
We represent a point by a pair (x,y) of ints, representing its (x,y) coordinates,
and a rectangle by the pair (a,b) of its lower-left and upper-right corners.
*)
type point = int * int
type rect = point * point
(* Purpose: compute the area of a rectangle.
Example: area ((1,2),(4,3)) = 3
area ((1,1),(4,3)) = 6
*)
fun area (r : rect) : int =
let val (ll, ur) = r
in
let val (llx, lly) = ll
in
let val (urx,ury) = ur
in
(urx - llx) * (ury - lly)
end
end
end
(* let is used for taking apart a pair, but when you have nested let's
like that, you can combine them like so: *)
fun area (r : rect) : int =
let val (ll, ur) = r
val (llx, lly) = ll
val (urx,ury) = ur
in (urx - llx) * (ury - lly)
end
(* since we only ever use ll and ur to take them apart, we can further
simplify this by doing nested pattern matching on the pairs *)
fun area (r : rect) : int =
let val ((llx, lly), (urx,ury)) = r
in (urx - llx) * (ury - lly)
end
(* since we only break apart r, we can also do that in the fun line *)
fun area ( ((llx, lly), (urx,ury)) : rect ) : int =
(urx - llx) * (ury - lly)
(* I tested by typing this into SMLNJ
- area ((1,2),(4,3));
val it = 3;
- area ((1,1),(4,3));
val it = 6;
*)
(* ---------------------------------------------------------------------- *)
(* another example from the homework handout *)
(* Purpose: Given an integer n, create a rectangle with both sides of
length n. Since the problem doesn't specify where the rectangle should
be located, this function puts the lower-left corner at (0,0).
Examples:
make_square 4 should be ((0,0),(4,4))
make_square 6 should be ((0,0),(6,6))
*)
fun make_square(n : int) : rect = ((0,0),(n,n))
(* I tested this interactively by typing the following into SMLNJ:
- make_square 4;
val it = ((0,0),(4,4))
- make_square 6;
val it = ((0,0),(6,6))
*)