Let's improve our code from last time.
type point = float * float
type shape =
(* lets represent a circle by it's center and it's radius*)
(* we can use the "of" keyword to make it carry more data*)
| Circle of {center: point; radius: float}
(* let's represent rectangles with their lower left
coordinate and their upper right coordiante.*)
| Rectangle of {lower_left: point; upper_right: point}
let c1 = Circle {center = (0., 0.); radius = 1.}
let r1 = Rectangle {lower_left = (-1., -1.); upper_right = (1., 1.)}
let avg a b = (a +. b) /. 2.;;
type point = float * float
type shape =
Circle of { center : point; radius : float; }
| Rectangle of { lower_left : point; upper_right : point; }
val c1 : shape = Circle {center = (0., 0.); radius = 1.}
val r1 : shape = Rectangle {lower_left = (-1., -1.); upper_right = (1., 1.)}
val avg : float -> float -> float = <fun>
We can actually nest our pattern matching, so that we don't need to match several times.
let center s =
match s with
| Circle {center; radius} -> center
| Rectangle {lower_left=(x_ll, y_ll); upper_right=(x_ur,y_ur)} ->
(avg x_ll x_ur, avg y_ll y_ur)
val center : shape -> point = <fun>
Nesting pattern matching can really help clean up your code. Let's add another shape!
type shape =
| Circle of {center: point; radius: float}
| Rectangle of {lower_left: point; upper_right: point}
| Point of point
type shape =
Circle of { center : point; radius : float; }
| Rectangle of { lower_left : point; upper_right : point; }
| Point of point
let p1 = Point (31., 10.)
val p1 : shape = Point (31., 10.)
let center s =
match s with
| Circle {center; radius} -> center
| Rectangle {lower_left=(x_ll, y_ll); upper_right=(x_ur,y_ur)} ->
(avg x_ll x_ur, avg y_ll y_ur)
File "[5]", lines 2-5, characters 1-32:
2 | .match s with
3 | | Circle {center; radius} -> center
4 | | Rectangle {lower_left=(x_ll, y_ll); upper_right=(x_ur,y_ur)} ->
5 | (avg x_ll x_ur, avg y_ll y_ur)
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Point _
val center : shape -> point = <fun>
Uh oh! We have a warning! Our center function is missing a pattern match for our newly created Point constructor. Let's fix that.
let center = function
| Circle {center; radius} -> center
| Rectangle {lower_left=(x_ll, y_ll); upper_right=(x_ur,y_ur)} ->
(avg x_ll x_ur, avg y_ll y_ur)
| Point p -> p
val center : shape -> point = <fun>
center p1;;
- : point = (31., 10.)
Note that we couldn't use Point _ here, because we need to capture the data held by the point. We could; however, write Point (x, y) -> (x, y), but we're doing extra pattern matching that we don't actually need to do if we do that.