在Haskell中如何计算列表中特定Int的数量

时间:2013-12-08 12:03:25

标签: list haskell

我正在尝试创建一个countElems函数Int,其中[Int]Int会返回列表中特定countElems :: Int -> [Int] -> Int countElems n (x:xs) | xs == [] = 0 | n == x = 1 + countElems n xs | n /= x = countElems n xs 的多少。到目前为止,我有:

countElems 9 [5, 3, 9, 3, 9]

运行时,这似乎有效,但在进一步检查时,如果输入1,则输出为2而不是xs == []。我可以看到这是因为它在查看n == x是否导致输出错误之前会检查Non-exhaustive pattern,但如果我将这两种情况交换为countElems :: Int -> [Int] -> Int countElems _ [] = 0 countElems n (x:xs) | n == x = 1 + countElems n xs | n /= x = countElems n xs

进一步思考后编辑:

我可以消除使用此代码发布的错误@ user2407038:

{{1}}

它看起来不那么优雅,但效果一样吗?

4 个答案:

答案 0 :(得分:5)

另一个没有任何递归子句的人:

countElem e = length . filter (e ==)

答案 1 :(得分:2)

在您的第一次检查(xs == [] = 0)中,您忘记检查x==n在哪种情况下结果应为1而不是0

countElems n (x:xs)
| xs == []   = if x==n then 1 else 0
| n == x     = 1 + countElems n xs
| n /= x     = countElems n xs

另一个(可能更直接)实现可能会将列表视为一个整体:

cE n [] = 0
cE n (x:xs) = (if n==x then 1 else 0) + (cE n xs)

答案 2 :(得分:2)

无论您将守卫放在哪个顺序,您的功能都不详尽。请考虑countElems 9 []。这是一个错误,因为没有模式匹配空列表。 (也许这是您的理想行为 - 但通常错误很糟糕)。考虑在这里使用模式匹配:

countElems n (x:xs) = fromEnum (n == x) + countElems n xs
countElems _ []     = 0

fromEnum避免了我喜欢的if,但你不必使用它。

这里可能没有必要使用显式递归。试试\x = length . filter (==x)

答案 3 :(得分:0)

您也可以使用map:

编写它
countElems :: Int -> [Int] -> Int
countElems n xs = sum $ map (fromEnum . (==n)) xs