在 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
采用谓词并告诉您提供的列表中有多少元素与该谓词匹配。
因此,如果您获得了 filter
ed 列表的 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)
但是,这需要两个函数,并且会做额外的工作。相反,您可以直接使用 Int
s 而不是 [Int]
s:
countP :: [a] -> (a -> Bool) -> Int
countP [] _ = 0
countP (x:xs) condition = ...
我仍然会让你在这里填空,知道你离正确的解决方案已经不远了。
但是,如果我要在项目中实现此代码,我会直接使用 length
和 filter
:
countP xs condition = length (filter condition xs)
这就是我所说的惯用定义(取决于参数顺序)。
我需要一个检查列表条件的函数。
例如:
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
采用谓词并告诉您提供的列表中有多少元素与该谓词匹配。
因此,如果您获得了 filter
ed 列表的 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)
但是,这需要两个函数,并且会做额外的工作。相反,您可以直接使用 Int
s 而不是 [Int]
s:
countP :: [a] -> (a -> Bool) -> Int
countP [] _ = 0
countP (x:xs) condition = ...
我仍然会让你在这里填空,知道你离正确的解决方案已经不远了。
但是,如果我要在项目中实现此代码,我会直接使用 length
和 filter
:
countP xs condition = length (filter condition xs)
这就是我所说的惯用定义(取决于参数顺序)。