【问题标题】:Standard ML: Ugly isLeapYear Function标准 ML:丑陋的 isLeapYear 函数
【发布时间】:2015-07-25 01:29:50
【问题描述】:

我正在尝试使用 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));

感谢您的帮助, 布莱曼

【问题讨论】:

    标签: functional-programming sml


    【解决方案1】:

    如果您不关心一些额外的说明:

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

    【讨论】:

      【解决方案2】:

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

      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,其中Es 之一是truefalse

      (请原谅丹麦的标题,它摘自《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)
      

      【讨论】:

        【解决方案3】:

        一般来说,只要你看到

        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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-19
          • 2014-01-16
          • 1970-01-01
          • 2018-06-11
          • 2012-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多