如何在Haskell中不导入Data.Char模块实现toUpper和toLower功能
问题排查与修复方案
现有代码的核心错误出在toLower''的判断逻辑完全倒置:转小写的功能要求将大写字母转为小写,所以应该判断输入字符是否属于大写字母区间['A' .. 'Z'],而非当前的小写区间。当前的toLower''逻辑会对本就小写的字符加32,得到ASCII码超出小写字母范围的异常字符,同时对大写字母不做任何转换,完全不符合预期。
修复后的完整代码如下:
toLower'' :: [Char]-> [Char] toLower'' [] = [] toLower'' (x : xs) -- 仅大写字母触发转小写逻辑 | x `elem` ['A' .. 'Z'] = toEnum (fromEnum x + 32) : toLower'' xs | otherwise = x : toLower'' xs toUpper'' :: [Char] -> [Char] toUpper'' [] = [] toUpper'' (x : xs) -- 仅小写字母触发转大写逻辑 | x `elem` ['a' .. 'z'] = toEnum (fromEnum x - 32) : toUpper'' xs | otherwise = x : toUpper'' xs
如果你需要和Haskell内置toUpper/toLower完全对齐的单字符处理函数,可以把逻辑抽离为单字符版本,再通过map作用到字符串上,简化实现:
-- 单字符转小写,与内置toLower功能对齐(仅支持ASCII英文字母) charToLower :: Char -> Char charToLower x | x `elem` ['A' .. 'Z'] = toEnum (fromEnum x + 32) | otherwise = x -- 单字符转大写,与内置toUpper功能对齐(仅支持ASCII英文字母) charToUpper :: Char -> Char charToUpper x | x `elem` ['a' .. 'z'] = toEnum (fromEnum x - 32) | otherwise = x -- 字符串处理直接复用单字符逻辑即可 toLowerStr :: [Char] -> [Char] toLowerStr = map charToLower toUpperStr :: [Char] -> [Char] toUpperStr = map charToUpper
注意:以上实现仅适配ASCII编码范围内的英文字母,和Haskell标准库中支持全Unicode字符集的
toUpper/toLower有差异,如需Unicode支持仍需要依赖Data.Char模块的相关实现。
内容的提问来源于stack exchange,提问作者I'veGotSomeQuestions
相关产品推荐
相关产品推荐

