对于这个功能才是最重要的是保持一个谓词列表中元素的个数,变换,如果别的模式匹配的递归函数
count :: (a -> Bool) -> [a] -> Int
count _ [] = 0
count p (x:xs) = (if (p x) then 1 else 0) + count p xs
如何将if-else
表达式转换到模式匹配,同时保留总和。
对于这个功能才是最重要的是保持一个谓词列表中元素的个数,变换,如果别的模式匹配的递归函数
count :: (a -> Bool) -> [a] -> Int
count _ [] = 0
count p (x:xs) = (if (p x) then 1 else 0) + count p xs
如何将if-else
表达式转换到模式匹配,同时保留总和。
你可以这样做:
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
我会改变'count'p(x:xs)|否则'只是'| otherwise'。 – chi 2014-10-20 12:08:51
您不能转换的if-else图案在函数定义的水平相匹配。模式匹配用于将值与其构造函数进行匹配。另一方面,If-else
针对True
和False
进行测试。
通过模式匹配,您可以决定基于值如何的样子,而不是值是什么。要测试其值是什么,请使用警卫或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
数据类型的构造,其具有两个构造匹配 - True
和False
,没有任何实际数据。
您可以使用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
这是一个有点不清楚你问什么,但您寻找的'数 'P(X:XS)真= 1 +算' P XS(PX ); count'p(x:xs)False = count'p xs(p x)'? – Zeta 2014-10-20 11:55:00
我不认为在这里切换到守卫/模式匹配是很聪明的。我会写你的函数为'count p = length'。过滤器p'完成。或者'count p = foldr(\ x - > if p x then(+1)else id)0':有时候if'一点都不坏,这当然比模式匹配好。 – leftaroundabout 2014-10-20 12:00:48
@leftaroundabout同意,也注意到这个理解'count'p xs = length [x | x < - xs,p x]',但想知道这个特定的转换... – elm 2014-10-20 12:02:24