匹配Haskell的类型错误

时间:2016-11-15 16:54:48

标签: haskell functional-programming

我已声明以下类型

data MonthData = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec deriving ( Eq, Show, Enum, Ord )
type Year = Int
type Month = ( MonthData, Year )



type Gap = Int
type Average = Double
type HistoryElem = ( Date, Gap, Average )
type History = [ HistoryElem ]

然后,我宣布了以下功能

event_tests = [ ( ( 28, ( Nov, 2016 ) ), 0, 0.0 ), ( ( 27, ( Nov, 2016 ) ), 0, 0.0 ) ]
history :: Int -> HistoryElem
history 0 = head( event_tests )

当我尝试加载文件时,出现以下错误。

ERROR "ass16-1.hs":90 - Type error in explicitly typed binding
*** Term           : history
*** Type           : Int -> ((Integer,(MonthData,Integer)),Integer,Double)
*** Does not match : Int -> HistoryElem

似乎它没有考虑先前已经定义过HistoryElem,因为如果我们看起来很谨慎,我们可以看到

((Integer,(MonthData,Integer)),Integer,Double)HistoryElem

的定义相同

无法弄清楚我做错了什么。

1 个答案:

答案 0 :(得分:3)

event_tests添加类型签名应该可以解决问题:

eventTests :: History
event_tests = [ ( ( 28, ( Nov, 2016 ) ), 0, 0.0 ), ( ( 27, ( Nov, 2016 ) ), 0, 0.0 ) ]

部分问题在于,正如类型错误所暗示的那样......

ERROR "ass16-1.hs":90 - Type error in explicitly typed binding
*** Term           : history
*** Type           : Int -> ((Integer,(MonthData,Integer)),Integer,Double)
*** Does not match : Int -> HistoryElem

... IntInteger的类型不同。如section 6.4 of the Haskell Report所指定,Int是固定大小的整数,而Integer可以是任意大小。这会影响您的代码,因为如果在任何地方都没有类型签名来指定整数文字应该是哪种类型,它将默认为Integer(请参阅section 4.3.4 of the report for details)。既然如此,28中的2016event_tests等整数默认为Integer,除非您指定其他类型(例如通过您的History类型同义词,这间接使他们成为Int s。。