我刚刚开始使用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)(这是正确的)。 有人能告诉我为什么我的第一个电话会导致这种模式匹配?因为我很确定我将列表作为参数
答案 0 :(得分: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
时除以零。
答案 1 :(得分:2)
如上所述,只需将[gradelist]
替换为gradelist
。此外,您可能希望使用[]匹配空列表,以避免在average
中除以零,如:
statistics [] = (0,0,0)
答案 2 :(得分:1)
模式中的列表语法[ ]
解构列表。模式[gradelist]
匹配一个只包含一个值的列表,并命名列表gradelist
中的值。如果您尝试使用包含四个值的列表调用该函数,则会出现模式匹配失败。
要匹配值而不解构它,请使用变量作为模式。