标准ML:Ugly isLeapYear功能

时间:2015-07-24 17:09:24

标签: functional-programming sml

我尝试使用case of在标准ML中编写一个函数,但我最终得到的代码却为一堆if / else而尖叫。这只是使用case of的不良候选人,还是有更好的方法来设置它,所以我不会经常将布尔值映射到布尔值?

这是我的代码:

fun isLeapYear(y) =
    case (y mod 400 = 0) of
        true => true |
        false => (case ((y mod 100 = 0)) of
            true => false |
            false => (case (y mod 4 = 0) of
                true => true |
                false => false));

感谢您的帮助, bclayman

3 个答案:

答案 0 :(得分:6)

如果您不在乎一些额外的指示:

fun isLeapYear(y) = case (y mod 400, y mod 100, y mod 4) of
    (0, _, _) => true 
  | (_, 0, _) => false
  | (_, _, 0) => true
  | (_, _, _) => false

答案 1 :(得分:5)

首先,case X of true => E1 | false => E2"直接对应if X then E1 else E2,我个人更喜欢。 (毕竟,if ... then ... else ...是一种专门的案例构造,只适用于布尔值,对吧?)把它变成了给我们:

fun isLeapYear(y) =
          if y mod 400 = 0 then true
     else if y mod 100 = 0 then false
     else if y mod   4 = 0 then true
     else                       false

这让我想到了第二点:您可以使用下表重写if B then E1 else E2,其中E之一是truefalse

Table of how to rewrite if statements containing bools

(原谅丹麦的标题,它取自本书" IP-2: Supplerende noter i Introduktion til programmering",我们用它来教授哥本哈根大学的SML。)

无论如何,使用这个重写,我们得到:

fun isLeapYear(y) =
              if y mod 400 = 0 then true
         else if y mod 100 = 0 then false
         else if y mod   4 = 0 then true
         else                       false

变为

fun isLeapYear(y) =
              if y mod 400 = 0 then true
         else if y mod 100 = 0 then false
         else                       y mod   4 = 0

变为

fun isLeapYear(y) =
              if y mod 400 = 0 then true
                               else not (y mod 100 = 0) andalso y mod 4 = 0

变为

fun isLeapYear(y) = y mod 400 = 0 orelse (not (y mod 100 = 0) andalso y mod 4 = 0)

最后,我们可以将not (y mod 100 = 0)转换为y mod 100 <> 0,并提供:

fun isLeapYear(y) = y mod 400 = 0 orelse (y mod 100 <> 0 andalso y mod 4 = 0)

答案 2 :(得分:2)

一般情况下,无论何时看到

case p of
  true => true
  | false => q

(或等效if p then true else q)你应该写

p orelse q

同样地

case p of
  false => false
  true => q

只是p andalso q

最后

case p of
  true => true
  false => false

只是p

所以你的例子写得更好

y mod 400 = 0
orelse (y mod 100 <> 0
        andalso y mod 4 = 0)