我正在尝试创建一个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}}
它看起来不那么优雅,但效果一样吗?
答案 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