Haskel的工作日与格里高利日历公式

时间:2017-12-07 07:41:50

标签: haskell weekday

第一个帮助的Thx。现在我换了这个。但仍然是一个沼泽错误。我的整个代码是错误的还是只有工作日功能的部分。 如何调用另一个函数内的函数?

data Wochentag = Mo | Di | Mi | Do | Fr | Sa | So
deriving (Eq, Ord, Show, Enum)

data Month = Jan | Feb | März | April | Mai | Juni | Juli | Aug | Sep | Okt | Nov | Dec
deriving (Eq, Ord, Show, Enum)


weekday :: Integer -> Month -> Integer -> Wochentag
weekday day month year = weekdays day (zahlmonth month) year

y1 = year - (14 - zahlmonth) /12
x = y1 + (y1 /4) - (y1 /100) + (y1 /400)
m = zahlmonth + 12 * ((14- zahlmonth) /12) -2


weekdays day zahlmonth year
    | mod (day + x + ((31*m) / 12)) 7 == 0 = So
    | mod (day + x + ((31*m) / 12)) 7 == 1 = Mo
    | mod (day + x + ((31*m) / 12)) 7 == 2 = Di 
    | mod (day + x + ((31*m) / 12)) 7 == 3 = Mi 
    | mod (day + x + ((31*m) / 12)) 7 == 4 = Do 
    | mod (day + x + ((31*m) / 12)) 7 == 5 = Fr
    | mod (day + x + ((31*m) / 12)) 7 == 6 = Sa 
    | otherwise = error "kein Tag"



zahlmonth :: Month -> Integer
zahlmonth month = case month of
  Jan -> 1
  Feb -> 2
  März -> 3
  April -> 4
  Mai -> 5
  Juni -> 6
  Juli -> 7
  Aug -> 8
  Sep -> 9
  Okt -> 10
  Nov -> 11
  Dec -> 12

错误日志是:

 Couldn't match expected type `Month -> Integer'
                  with actual type `Integer'
    * In the first argument of `weekdays', namely `day'
      In the expression: weekdays day (zahlmonth month) year
      In an equation for `weekday':
          weekday day month year = weekdays day (zahlmonth month) year
   |
95 | weekday day month year = weekdays day (zahlmonth month) year
   |                                   ^^^

   Variable not in scope: year :: Month -> Integer
   |
97 | y1 = year - (14 - zahlmonth) /12
   |      ^^^^

完全奇怪,但不知道如何解决它。当我给工作日的描述时,它变得更糟。

1 个答案:

答案 0 :(得分:0)

这里的问题是您没有为所有顶级绑定添加类型,因此其中一些被推断为错误的类型。如果只有类型注释,GHC会立即报告错误,但如果没有,GHC无法看到推断类型是错误的,因此将其视为面值。

很久以后,错误的类型会导致问题,只有这样,GHC才能报告问题 - 关于不相关的代码。

更详细,这里发生了什么:

m = zahlmonth + ...

此处zahlmonth是一个函数Month -> Integer。由于+的结果类型与参数相同,因此m也是函数Month -> Integer

如果m :: Integer出现,GHC会因错误而停在这里。但是,唉,GHC不知道这就是问题所在。

然后,

weekdays day zahlmonth year
    | mod (day + x + ((31*m) / 12)) 7 == 0 = So

由于操作+,*,/在同一类型上工作,我们得到了 dayx具有相同类型的m,即Month -> Integer

如果weekdays有类型签名,GHC会发现错误,但如果没有,它会很乐意继续。

最后,

weekday day month year = weekdays day (zahlmonth month) year

此处weekday有签名,说day :: Integer。但上面我们推断weekdays期望day :: Month -> Integer。这会触发类型错误

 Couldn't match expected type `Month -> Integer'
                  with actual type `Integer'
    * In the first argument of `weekdays', namely `day'

这是非常清楚的,在理解推理过程中发生了什么之后。

关键是,然而,...理解在推理过程中发生的事情并不容易!一般来说,很难跟随GHC自动推断程序周围的类型。幸运的是,这是不需要的,只要仔细编写代码,注释绑定上的类型,以便尽可能早地捕获类型错误。