對於這個功能纔是最重要的是保持一個謂詞列表中元素的個數,變換,如果別的模式匹配的遞歸函數
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