高阶函数haskell

G. *_*Zam 4 string haskell fold higher-order-functions

我是Haskell的新手,我要做一个函数,使用高阶函数foldr计算字符串中元音的数量

我试过创建这个功能

vowels [] = 0
vowels (x:xs)= if elem x "aeiou" then 1 + vowels xs else vowels xs
Run Code Online (Sandbox Code Playgroud)

但它不起作用,我无法使用foldr任何建议吗?

Wil*_*sem 8

井a foldr :: (a -> b -> b) -> b -> [a] -> b是第一个参数是函数的函数f :: a -> b -> b.您可以在此处将a参数视为列表的" 头部 ",第二个参数b作为递归的结果,foldr因此您希望根据这两个参数为整个函数生成结果.该逻辑基本上封装在函数的第二个子句中.

确实:

vowels (x:xs) = if elem x "aeiou" then 1 + vowels xs else vowels xs
Run Code Online (Sandbox Code Playgroud)

可以改写为:

vowels (x:xs) = if elem x "aeiou" then 1 + rec else rec
    where rec = vowels xs
Run Code Online (Sandbox Code Playgroud)

并且rec因此是递归调用中,"折叠" -函数的第二个参数的结果.x另一方面是"折叠"功能的第一个参数.因此,我们需要编写此函数,仅用于xrec,这简单地说:

\x rec -> if elem x "aeiou" then 1 + rec else rec
Run Code Online (Sandbox Code Playgroud)

此外,我们需要处理空列表的情况,这是您的函数的第一个子句.在这种情况下,结果是0,这是第二个参数foldr,所以我们得到:

vowels = foldr (\x rec -> if elem x "aeiou" then 1 + rec else rec) 0
Run Code Online (Sandbox Code Playgroud)

或者更简洁的语法:

vowels = foldr f 0
    where f x rec | elem x "aeiou" = 1 + rec
                  | otherwise = rec
Run Code Online (Sandbox Code Playgroud)

我们可以通过抽象来进一步清理它rec:

vowels = foldr f 0
    where f x | elem x "aeiou" = (1+)
              | otherwise = id
Run Code Online (Sandbox Code Playgroud)