下面的函数计算元音和辅音的数量:
'''
countVowelConsonant :: [Char] -> Int
countVowelConsonant cs = count v c cs
where
v = 0
c = 0
count :: Int -> Int -> [Char] -> Int
count v c [] = comp v c
where
comp v c
| v == c = 0
| v > c = v
| otherwise = c
count v c (a:cs)
| or [a == 'a', a == 'e', a == 'i', a == 'o', a == 'u'] = count (v+1) c cs
| otherwise = count v (c+1) cs
main :: IO()
main = do
print $ countVowelConsonant ['a','l','l']
'''
如何进一步优化,看起来有点乱
代码片段如下:
countVowelConsonant :: [Char] -> Int
countVowelConsonant cs = count v c cs
where
v = 0
c = 0
看起来很奇怪:在Haskell中,变量是不可变的,所以你不能递增或递减
v
或c
,所以定义一个变量v = 0
,然后将它传递给函数是非常奇怪的。
但我们并不真正需要这个。我们只需要实现一个元音检查功能即可:
isVowel :: Char -> Bool
isVowel 'a' = True
isVowel 'e' = True
isVowel 'i' = True
isVowel 'o' = True
isVowel 'u' = True
isVowel 'A' = True
isVowel 'E' = True
isVowel 'I' = True
isVowel 'O' = True
isVowel 'U' = True
isVowel _ = False
然后我们计算元音和辅音的数量:
countBoth :: (a -> Bool) -> [a] -> (Int, Int)
countBoth pred = go 0 0
where
go t f [] = (t, f)
go t f (x : xs)
| pred x = t `seq` go (t + 1) f xs
| otherwise = f `seq` go t (f + 1) xs
然后我们可以对结果进行后处理,例如:
countVowelConsonant :: String -> Int
countVowelConsonant cs = go (countBoth isVowel cs)
where
go (v, c)
| v == c = 0
| otherwise = max v c