2013-03-26 41 views
2

我刚开始使用Haskell,偶然发现问题。根据Haskell,我有一个模式匹配失败,但我看不出如何。 这是我尝试执行代码:Haskell中的列表中的模式匹配失败

statistics :: [Int] -> (Int, Int, Int) 
statistics [gradelist] = (amountParticipants, average, amountInsufficient) 
         where 
          amountParticipants= length [gradelist] 
          average= sum[gradelist] `div` amountParticipants 
          amountInsufficient= length [number| number<- [gradelist], number<6] 

我称之为与 '统计':

statistics[4,6,4,6] 

这会导致模式匹配失败,而我希望看到:(4,5,2 )

statistics[6] 

给出了答案:(1,6,0)(这是正确的)。 有人能告诉我为什么我的第一个电话会导致这种模式匹配吗?因为我敢肯定,我给一个列表作为参数

+4

'[gradelist]'只匹配一个元素的列表。整个过程只使用'gradelist'。 – 2013-03-26 13:55:42

回答

7

如果你写statistics [gradelist] = ...你是对含有唯一的元素的列表模式匹配称gradelist。因此,你的函数只能定义长度为1的列表(例如[6]);对于空列表([])或包含两个或更多元素(例如[4,6,4,6])的列表未定义。

你的函数的正确文将

statistics :: [Int]  -> (Int, Int, Int) 
statistics gradelist = (amountParticipants, average, amountInsufficient) 
    where 
    amountParticipants = length gradelist 
    average   = sum gradelist `div` amountParticipants 
    amountInsufficient = length [number| number <- gradelist, number < 6] 

由于@thoferon说,计算的时候,你也将需要为其中gradelist是空的情况下的特殊安排,以避免被零除average

+0

感谢您的快速反应!现在我终于可以继续使用这种语言^^ – 2013-03-26 14:39:20

1

模式中的列表语法[ ]解构列表。模式[gradelist]与仅包含一个值的列表匹配,并将其列入列表gradelist中的值。如果尝试使用包含四个值的列表调用函数,则会出现模式匹配失败。

要匹配没有解构它的值,请使用变量作为模式。

2

正如前面所说的,只需用gradelist替换您的[gradelist]即可。此外,您可能要匹配与[]空列表,以避免被零除average,如:

statistics [] = (0,0,0)