我需要一个检查列表中条件的函数。
例如:
countP :: [a] -> (a -> Bool) -> Int
输入:
countP [1,-2,0,-1,5] (>0)
应返回2,因为有两个大于零的数字。
这是我到目前为止所做的:
countP :: [a] -> (a -> Bool) -> Int
countP [] _ = []
countP (x:xs) condition = if condition x then 1:countP xs condition else countP xs condition
它返回[1,1]而不是第二个。它必须是递归的。
我该怎么做?
答案 0 :(得分:2)
您必须添加结果,例如
countP :: [a] -> (a -> Bool) -> Int
countP [] _ = 0
countP (x:xs) condition = (if condition x then 1 else 0) + (countP xs condition)
每当condition x
评估为True时,我们会1
使用0
,我们会递归调用countP
并添加它们。
所以,当你像这样调用它时
countP [1, -2, 0, -1, 5] (>0)
它将被递归评估,就像这个
一样(if (> 0) 1 then 1 else 0) + (countP [-2, 0, -1, 5] (> 0))
1 + (countP [-2, 0, -1, 5] (> 0))
1 + (if (> 0) -1 then 1 else 0) + (countP [0, -1, 5] (> 0))
1 + 0 + (countP [0, -1, 5] (> 0))
1 + 0 + 0 + (countP [-1, 5] (> 0))
1 + 0 + 0 + 0 + (countP [5] (> 0))
1 + 0 + 0 + 0 + 1 + (countP [] (> 0))
1 + 0 + 0 + 0 + 1 + 0 = 2
由于我们的递归函数(countP [] (> 0))
的基本条件, 0
被评估为countP [] _ = 0
。这意味着无论第二个参数是什么,如果第一个参数是空列表,则返回0。
答案 1 :(得分:2)
你好像在想这个。您可以使用一些Prelude提供的函数并将它们组合以产生结果:
length $ filter (>0) [1,-2,0,-1,5]
length
会列出一个列表并告诉您它有多长。
filter
接受谓词并告诉您提供的列表中有多少元素与该谓词匹配。
因此,如果您获得了length
ed列表的filter
,那么您已设置。
countP xs f = length $ filter f xs
答案 2 :(得分:1)
有一个专门用于计算列表中事物数量的函数,它被称为length
。你可以做点什么
countP' [] _ = []
countP' (x:xs) condition = if condition x then 1 : countP' xs condition else countP' xs condition
countP xs condition = length (countP' xs condition)
然而,这需要两个功能,它可以完成额外的工作。相反,您可以直接使用Int
s代替[Int]
s:
countP :: [a] -> (a -> Bool) -> Int
countP [] _ = 0
countP (x:xs) condition = ...
我仍然会让你填补这里的空白,知道你与现有的解决方案并不是很正确。
但是,如果我要在项目中实现此代码,我只需访问length
和filter
:
countP xs condition = length (filter condition xs)
这就是我所说的惯用语定义(直到参数顺序)。