第一个帮助的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
| ^^^^
完全奇怪,但不知道如何解决它。当我给工作日的描述时,它变得更糟。
答案 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
由于操作+,*,/
在同一类型上工作,我们得到了
day
,x
具有相同类型的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自动推断程序周围的类型。幸运的是,这是不需要的,只要仔细编写代码,注释绑定上的类型,以便尽可能早地捕获类型错误。