如果不是,则转换为递归函数中的模式匹配



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

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

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

不能在函数定义级别将 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 ,没有任何实际数据。

你可以做:

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

您可以使用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

最新更新