在 Haskell 中验证条件

Verifying condition in Haskell

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

例如:

countP :: [a] -> (a -> Bool) -> Int

输入:

countP [1,-2,0,-1,5] (>0)

应该return2,因为有两个数大于零。

这是我目前所做的:

countP :: [a] -> (a -> Bool) -> Int
countP [] _ = []
countP (x:xs) condition = if condition x then 1:countP xs condition else countP xs condition 

这是 returning [1,1] 而不是第二个。它必须是递归的。

我该怎么做?

你必须添加结果,像这样

countP :: [a] -> (a -> Bool) -> Int
countP [] _ = 0
countP (x:xs) condition = (if condition x then 1 else 0) + (countP xs condition)

每当 condition x 计算为真时,我们使用 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。意思是不管第二个参数是什么,如果第一个参数是空列表,那么return0.

你好像想多了。您可以使用 Prelude 提供的一些函数并组合它们以生成结果:

length $ filter (>0) [1,-2,0,-1,5]

length 将获取一个列表并告诉您它有多长。 filter 采用谓词并告诉您提供的列表中有多少元素与该谓词匹配。 因此,如果您获得了 filtered 列表的 length,那么您就完成了。

countP xs f = length $ filter f xs

有一个函数专门用来计算列表中事物的数量,它叫做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)

但是,这需要两个函数,并且会做额外的工作。相反,您可以直接使用 Ints 而不是 [Int]s:

countP :: [a] -> (a -> Bool) -> Int
countP [] _ = 0
countP (x:xs) condition = ...

我仍然会让你在这里填空,知道你离正确的解决方案已经不远了。

但是,如果我要在项目中实现此代码,我会直接使用 lengthfilter:

countP xs condition = length (filter condition xs)

这就是我所说的惯用定义(取决于参数顺序)。