Reputation: 37
I have this OCaml code:
type primary_color = Red | Green | Blue
let r = Red
type point = float * float
type shape =
| Circle of {center : point; radius : float}
| 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.
and the following center
functions that calculate the center of the different shapes:
(* Function one using let (...) = ... *)
let center s =
match s with
| Circle {center; radius} -> center
| Rectangle {lower_left; upper_right} ->
let (x_ll, y_ll) = lower_left in
let (x_ur, y_ur) = upper_right in
(avg x_ll x_ur, avg y_ll y_ur)
(* Function two using nested pattern matching Rec{ a = ..., b = ...} *)
let center s =
match s with
| Circle {center; radius} -> center
| Rectangle {lower_left = (x_l, y_l); upper_right = (x_r, y_r)} ->
(avg x_l x_r, avg y_l y_r)
| Point p -> p
I don't fully understand the way the pattern syntax is working here.
how are in the first and second functions for calculating the center the values x_ll
and y_ll
just handed over to the function avg
? Because a) the pair (x_ll, y_ll)
isn't assigned to a variable and b) the values from the Pairs are just handed over without using for example let x_ll (a, b) = a
Upvotes: 0
Views: 315
Reputation: 36536
Both center
functions are accomplishing the same thing. The first one is just being a bit more roundabout. Though the first one doesn't match against Point
which your earlier code doesn't define.
If you still needed the names for the two tuples, you could use as
.
let center s =
match s with
| Circle {center; radius} -> center
| Rectangle {lower_left = (x_l, y_l) as ll;
upper_right = (x_r, y_r) as ur} ->
(avg x_l x_r, avg y_l y_r)
Structural pattern matching is very powerful, and it isn't limited to a certain number of levels. Consider a very simple example.
type a = {b: int}
type c = {d: a}
type e = {f: c}
let g = {f={d={b=42}}}
We can match directly to that int
.
match g with
| {f={d={b=n}}} -> n
Or even leave out the =n
.
match g with
| {f={d={b}}} -> b
We can also do this in a let
binding.
let {f={d={b=n}}} = g in
n
Upvotes: 2