我对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)
我认为filter函数正在删除空格,因此它变成了单个字符串。
那是正确的。作为过滤谓词,您可以编写\x -> x `elem` ['a'..'z']。['a'..'z']是包含小写字母的列表,因此对于空白,谓词将失败,因此您也应允许使用空格。
例如,我们可以将空格字符添加到列表中:
dropNonLetters xs = words $ (filter (\x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xsRun Code Online (Sandbox Code Playgroud)
但这并不雅致,也无法真正解释。Data.Char但是,该模块附带了两个有趣的功能:isLower :: Char -> Bool和和isSpace :: Char -> Bool。我们可以这样使用:
dropNonLetters xs = words $ (filter (\x -> isLower x || isSpace x)) $ toLowerStr xsRun Code Online (Sandbox Code Playgroud)
isLower而且isSpace不仅更具“描述性”和优雅。通常,这些功能比成员资格检查(通常在O(n)中完成)要快,而且还要考虑制表符,换行等。
我们还可以对函数执行eta归约:
dropNonLetters = words . (filter (\x -> isLower x || isSpace x)) . toLowerStrRun Code Online (Sandbox Code Playgroud)
然后产生:
Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]
Run Code Online (Sandbox Code Playgroud)
我建议您重命名该函数dropNonLetters,因为现在它不能完全说明它将生成单词列表。基于名称,我认为它只会删除非字母,不是将字符串转换为小写字母,也不是构造单词。