将if if转换为递归函数中的模式匹配

时间:2014-10-20 11:49:05

标签: haskell recursion pattern-matching

对于此函数,它计算列表中包含谓词的元素数量,

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

如何在保留求和的同时将if-else表达式转换为模式匹配。

3 个答案:

答案 0 :(得分:3)

您无法在函数定义级别将if-else转换为模式匹配。模式匹配用于将值与其构造函数进行匹配。另一方面,If-else针对TrueFalse进行了测试。

通过模式匹配,您可以根据 值来决定,而不是 值。要测试值是什么,可以使用警卫或if-else表达式。

但是,您可以使用case-of表达式将其转换为模式匹配:

count' :: (a -> Bool) -> [a] -> Int
count' _ [] = 0
count p (x:xs) = case (p x) of
                     True  -> 1 + count' p xs
                     False -> count' p xs

这是与Bool数据类型的构造函数的模式匹配,它有两个构造函数 - TrueFalse,没有任何实际数据。

答案 1 :(得分:2)

你可以这样做:

count' :: (a -> Bool) -> [a] -> Int
count' _ [] = 0
count' p (x:xs) | p x = 1 + count' p xs
count' p (x:xs) | otherwise = 0 + count' p xs

答案 2 :(得分:1)

您可以使用Data.Bool模块中的bool函数进行模式匹配。

bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True  = t

所以,

count :: (a -> Bool) -> [a] -> Int
count _ [] = 0
count p (x:xs)  = bool 0 1 (p x) + count p xs