SML和功能编码风格



我开始学习标准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

代码可以正常工作,但是看起来很丑。

如何用函数式风格重写这段代码?

两个建议:

  • 使用模式匹配来分解元组
  • 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)

最新更新