Haskell列表推导式意外移除首字符问题排查
问题排查:列表推导式意外丢失首字符的原因
嘿,我一眼就看到你代码里的问题啦!咱们来拆解一下你的noSpace函数:
noSpace (x:xs) = [x | x <- xs, x /= ' ']
这里有两个容易踩的小坑:
- 你用模式匹配
(x:xs)把输入字符串拆成了首字符x和剩余字符列表xs,但你完全没把这个首字符x加入到最终结果里!它被提取出来后就直接被丢弃了,根本没参与后续的处理。 - 列表推导式里的变量名也是
x,这相当于重新定义了一个局部变量x,它遍历的是xs里的元素——和你模式匹配出来的那个首字符x没有半毛钱关系,这就导致整个函数只处理了原字符串从第二个字符开始的部分。
所以当你传入"8 j 8 mBliB8g imjB8B8 jl B"时,开头的'8'直接被丢掉,剩下的字符过滤空格后自然就少了开头的那个8。
修正方案
其实根本不需要模式匹配,直接处理整个字符串就好啦,有两种简洁的写法:
写法1:修正列表推导式
直接遍历整个输入字符串,不用拆分首字符:
noSpace :: String -> String noSpace s = [c | c <- s, c /= ' ']
写法2:用filter函数更简洁
Haskell的filter函数天生就是干这个活的,一行就能搞定:
noSpace :: String -> String noSpace = filter (/= ' ')
用这两种写法跑你的测试代码,输出就是你预期的"8j8mBliB8gimjB8B8jlB"啦!
内容的提问来源于stack exchange,提问作者Ericson Willians
相关产品推荐
相关产品推荐

