我尝试使用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
答案 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
之一是true
或false
:
(原谅丹麦的标题,它取自本书" 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)