验证Haskell中的条件

时间:2015-01-16 15:26:37

标签: list haskell recursion

我需要一个检查列表中条件的函数。

例如:

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]而不是第二个。它必须是递归的。

我该怎么做?

3 个答案:

答案 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 = ...

我仍然会让你填补这里的空白,知道你与现有的解决方案并不是很正确。

但是,如果我要在项目中实现此代码,我只需访问lengthfilter

countP xs condition = length (filter condition xs)

这就是我所说的惯用语定义(直到参数顺序)。