SML和函数式编程风格

6
我正在学习编程语言课程,学习标准ML。
在第一次作业中,我尝试编写一个函数is_older,它接受两个日期并评估为truefalse。如果第一个参数是早于第二个参数的日期,则评估为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

这段代码运行良好,但外观很丑。

我该如何使用函数式风格重写此代码?

3个回答

13

两个建议:

  • 使用模式匹配来分解元组。
  • if/else构造返回布尔值时,使用布尔运算符(例如andalsoorelse等)。

更易读的版本:

(* 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)

9
一般来说,当您遇到以下形式的内容时:

...

if b then
  true
else
  false

你应该将其与只有b的替换,因为它可以被简单地看作是相同的。

当你最终拥有那些令人讨厌/嵌套的if-then-else语句,并且你没有返回简单的东西(例如true/false或数字),那么你应该考虑使用case语句。尽管你的函数不是使用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

1
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)

1
添加一些注释将有助于其他人理解您的答案建议。 - Yaroslav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接