I'm start to learn Standard ML with Programming languages course.
In the first homework, I try to write a function is_older
that takes two dates and evaluates to true
or false
. It evaluates to true
if the first argument is a date that comes before the second argument (If the two dates are the same, the result is false
.).
So I write the following code:
fun is_older(first: int * int * int, second: int * int * int) =
if(#1 first = #1 second andalso #2 first = #2 second andalso #3 first = #3 second) then false
else if (#1 first < #1 second) then true
else if (#1 first = #1 second andalso #2 first < #2 second) then true
else if (#1 first = #1 second andalso #2 first = #2 second andalso #3 first < #3 second) then true
else false
The code is works fine, but it looks ugly.
How can I rewrite this code in functional style?
Two suggestions:
andalso
, orelse
, etc.) when if/else
constructs return boolean.A more readable version:
(* Compare two dates in the form of (year, month, day) *)
fun is_older((y1, m1, d1), (y2, m2, d2)) =
y1 < y2 orelse (y1 = y2 andalso m1 < m2)
orelse (y1 = y2 andalso m1 = m2 andalso d1 < d2)
In general when you have something on the form
if b then
true
else
false
you should exchange it with just b
, as it is seen trivially to be the same.
The solution provided by pad would probably also have been my solution, as it is nice and short.
However when you end up having those nasty/nested if-then-else's, and you don't return something simple (e.g., true/false or a number), then you should consider using a case. Your function is not a prime candidate to use, however I hope the below still shows the idea (that you easily can make structure of those nested if's)
fun is_older((y1, m1, d1), (y2, m2, d2)) =
case (Int.compare(y1,y2), Int.compare(m1,m2), Int.compare(d1, d2)) of
(LESS , _ , _ ) => true
| (EQUAL, LESS , _ ) => true
| (EQUAL, EQUAL, LESS) => true
| _ => false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With