Haskell Haskel工作日,采用公历日历公式

Haskell Haskel工作日,采用公历日历公式,haskell,weekday,Haskell,Weekday,谢谢你的第一个帮助。现在我改变了这个。但仍然是一个错误。是我的全部代码都错了,还是只是带有平日函数的部分。 如何在另一个函数中调用函数 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

谢谢你的第一个帮助。现在我改变了这个。但仍然是一个错误。是我的全部代码都错了,还是只是带有平日函数的部分。 如何在另一个函数中调用函数

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
   |      ^^^^

完全奇怪,但不知道如何修复它。当我对工作日进行描述时,情况变得更糟。

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

很久以后,错误的类型将导致问题,只有到那时GHC才会报告问题——在不相关的代码上

更详细地说,下面是发生的情况:

m = zahlmonth + ...
这里的
zahlmonth
是一个函数
Month->Integer
。由于
+
的结果类型与参数相同,
m
也是一个函数
Month->Integer

如果存在
m::Integer
,GHC将在这里停止并出现错误。但是,唉,GHC不知道这就是问题所在

那么

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

如果
工作日
有一个类型签名,GHC会发现错误,但如果没有它,它会很高兴地继续

最后,

weekday day month year = weekdays day (zahlmonth month) year
这里的
weekday
有一个签名,表示
day::Integer
。但是上面我们推断出
工作日
期望
日::月->整数
。这会触发类型错误

 Couldn't match expected type `Month -> Integer'
                  with actual type `Integer'
    * In the first argument of `weekdays', namely `day'
这是非常清楚的,在一个人理解了上面的推理过程中发生了什么之后


然而,关键是。。。理解推理过程中发生的事情一点也不容易!一般来说,很难跟随GHC自动推断程序中的类型。幸运的是,如果您仔细编写代码,在绑定上注释类型,以便尽早发现类型错误,则不需要这样做。

您应该始终通过提供类型注释来启动函数,以声明您的意图。否则,GHC将推断您的函数类型,但在类型错误的情况下,GHC无法将其推断的类型与您的预期类型进行比较,只生成更模糊的错误消息。我现在编辑了它,这些y1、x、m的意思是什么,以及在哪里定义了年,x和m是根据公历方法计算给定日期的日期。年是同一个整数变量,它被赋予工作日。“从公历的角度看”它们是常数吗?他们是什么类型的?它们是顶级名称,请为它们提供类型注释。还有,
(14-zahlmonth)
是什么意思
zahlmonth
是类型为
Month->Integer
的函数。
 Couldn't match expected type `Month -> Integer'
                  with actual type `Integer'
    * In the first argument of `weekdays', namely `day'