2016-11-15 82 views
0

我已经宣布了以下类型错误类型匹配哈斯克尔

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先前已定义的,因为如果我们看carefuly,我们可以看到,

((Integer,(MonthData,Integer)),Integer,Double)是一样的定义比HistoryElem

想不通我做错了什么。

+7

'Date'定义在哪里? – Alec

+2

当发生类型错误时,将类型签名添加到所有顶级绑定可以大大简化它。大多数Haskellers将其作为最佳实践。事实上,有时候这个错误是在后来发现的,在一个令人惊讶的地方,一切看起来都很好 - 但是真正的错误要早得多,而且没有被发现只是因为编译器推断出了与你期望的类型不同的类型。使用类型注释会使编译器报告错误的位置。 – chi

回答

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)。因此,和2016等整数在event_tests中默认为Integer,除非您指定了其他类型(例如,通过您的History类型同义词,这会间接地使它们成为Int s)。