我开始学习标准ML与编程语言课程。
在第一个作业中,我尝试写一个函数is_older
,它需要两个日期并计算为true
或false
。如果第一个参数是在第二个参数之前的日期,则计算结果为true
(如果两个日期相同,则结果为false
)。
所以我写了下面的代码:
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
代码可以正常工作,但是看起来很丑。
如何用函数式风格重写这段代码?
两个建议:
- 使用模式匹配来分解元组
- 当
if/else
构造返回布尔值时使用布尔运算符(andalso
,orelse
等)。
更易读的版本:
(* 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)
通常当你在表单上有一些东西
if b then
true
else
false
您应该将其与b
交换,因为它通常是相同的。pad提供的解决方案可能也是我的解决方案,因为它很好而且简短。
然而,当你最终有那些讨厌的/嵌套的if-then-else时,并且你不返回一些简单的东西(例如,真/假或数字),那么你应该考虑使用case。你的函数不是一个主要的候选使用,但我希望下面仍然显示的想法(你可以很容易地使那些嵌套的if的结构)
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
fun is_older((yr1 : int , mo1 : int , dt1 : int), (yr2 : int , mo2 : int , dt2 : int )) =
yr1 < yr2 orelse (yr1 = yr2 andalso mo1 < mo2)
orelse (yr1 = yr2 andalso mo1 = mo2 andalso dt1 < dt2)