如何用foldr实现字符串去空格并将单词首字母大写?
用foldr实现去除空格并大写单词首字母
你已经用map实现了正确的版本:
deleteSpaces:: String -> String deleteSpaces word = (filter(not . isSpace) .unwords . map (\(x:xs) -> (toUpper x):xs) . words) word
但foldr版本的代码存在类型错误,先将错误信息翻译如下:
• 无法匹配类型‘Char’与‘[Char]’
期望类型:String
实际类型:Char
• 在‘(:)’的第一个参数位置,即‘(toUpper x)’
在表达式:(toUpper x) : xs : acc
在‘foldr’的第一个参数中,即‘(\ (x : xs) acc -> (toUpper x) : xs : acc)’
错误原因
words函数返回的是[String]类型的列表,每个元素是一个单词。foldr需要将处理后的完整单词(String类型)添加到累加器acc([String]类型)中。你原来的代码里,(toUpper x) : xs : acc的括号逻辑错误:这个表达式等价于(toUpper x) : (xs : acc),其中xs : acc是[String]类型,而toUpper x是Char类型,显然无法将Char加到[String]列表前,导致类型不匹配。
修正后的foldr版本
只需要调整括号,把处理后的完整单词作为一个元素添加到累加器即可:
deleteSpacesF :: String -> String deleteSpacesF word = (filter(not . isSpace) . unwords . foldr (\(x:xs) acc -> (toUpper x : xs) : acc) [] . words) word
如果要兼容空单词(虽然words会自动过滤掉空字符串),也可以用case表达式处理:
deleteSpacesF :: String -> String deleteSpacesF word = (filter(not . isSpace) . unwords . foldr (\w acc -> case w of [] -> acc x:xs -> (toUpper x : xs) : acc) [] . words) word
修正后,foldr会将每个单词首字母大写后,作为完整元素加入累加器列表,后续的unwords和filter逻辑和map版本一致,最终得到正确结果。
内容的提问来源于stack exchange,提问作者zeppal
相关产品推荐
相关产品推荐

