Haskell-删除非字母字符但忽略空格?

Big*_*ile 4 haskell

我对Haskell非常陌生。我正在尝试从给定的字符串(可能包含非字母字符)返回字符串列表,但是列表中只有一个字符串。

下面的代码显示了到目前为止我已经尝试过的内容:

toLowerStr xs = map toLower xs

--drop non-letters characters
dropNonLetters xs = words $ (filter (\x -> x `elem` ['a'..'z'])) $ toLowerStr xs
Run Code Online (Sandbox Code Playgroud)
  • 通过使用toLower函数将所有字符小写
  • 使用filter功能删除非字母字符
  • 通过使用words函数返回字符串列表

我认为该filter功能正在删除空格,因此它成为单个字符串。我尝试使用isSpace函数,但在这种情况下我不知道该如何实现。

我做错了什么?我得到以下输出:

?> dropNonLetters "ORANGE, apple! APPLE!!"
["orangeappleapple"]
Run Code Online (Sandbox Code Playgroud)

但我想实现以下输出:

?> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 5

我认为filter函数正在删除空格,因此它变成了单个字符串。

那是正确的。作为过滤谓词,您可以编写\x -> x `elem` ['a'..'z']['a'..'z']是包含小写字母的列表,因此对于空白,谓词将失败,因此您也应允许使用空格。

例如,我们可以将空格字符添加到列表中:

dropNonLetters xs = words $ (filter (\x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xs
Run Code Online (Sandbox Code Playgroud)

但这并不雅致,也无法真正解释。Data.Char但是,该模块附带了两个有趣的功能:isLower :: Char -> Bool和和isSpace :: Char -> Bool。我们可以这样使用:

dropNonLetters xs = words $ (filter (\x -> isLower x || isSpace x)) $ toLowerStr xs
Run Code Online (Sandbox Code Playgroud)

isLower而且isSpace不仅更具“描述性”和优雅。通常,这些功能比成员资格检查(通常在O(n)中完成)要快,而且还要考虑制表符,换行等。

我们还可以对函数执行eta归约

dropNonLetters = words . (filter (\x -> isLower x || isSpace x)) . toLowerStr
Run Code Online (Sandbox Code Playgroud)

然后产生:

Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]
Run Code Online (Sandbox Code Playgroud)

我建议您重命名该函数dropNonLetters,因为现在它不能完全说明它将生成单词列表。基于名称,我认为它只会删除非字母,不是将字符串转换为小写字母,也不是构造单词。