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

时间:2017-12-21 13:57:04

标签: haskell

我对Haskell很新。我试图从给定的字符串(可能包含非字母字符)返回字符串列表,但我在列表中得到一个字符串。

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

channel = sound0.play()
channel.set_volume(1.0, 0.0)
  • 使用toLowerStr xs = map toLower xs --drop non-letters characters dropNonLetters xs = words $ (filter (\x -> x `elem` ['a'..'z'])) $ toLowerStr xs 函数
  • 小写所有字符
  • 使用toLower功能
  • 删除非字母字符
  • 使用filter函数
  • 返回字符串列表

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

我做错了什么?我得到了这个输出:

isSpace

但我想实现以下输出:

λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orangeappleapple"]

2 个答案:

答案 0 :(得分:5)

  

我认为过滤器功能正在删除空格,因此它变为单个字符串。

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

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

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

但这不够优雅,并没有真正解释自己。然而,Data.Char模块附带了两个有趣的功能:isLower :: Char -> BoolisSpace :: Char -> Bool。我们可以使用它:

dropNonLetters xs = words $ (filter (\x -> isLower x || isSpace x)) $ toLowerStr xs

isLowerisSpace不仅仅是更多"描述性的"和优雅。通常这些功能比会员检查更快(通常在 O(n)中完成),此外它还会考虑标签,新行等。

我们还可以对该功能执行 eta-reduction

dropNonLetters = words . (filter (\x -> isLower x || isSpace x)) . toLowerStr

然后产生:

Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]

我建议你重命名函数dropNonLetters,因为现在它没有完全解释它会生成一个单词列表。根据名称,我认为它只会丢弃非字母,而不是将字符串转换为小写,也不会构造单词。

答案 1 :(得分:1)

下面是将字符分成单独的字符串列表的示例:

  

sortNumbers :: [字符]-> [字符串]   sortNumbers参数=过滤器(\ strings-> strings / =“”)$ zipWith(\ x数字->过滤器(\ char-> char ==数字)x)(重复args)   ['1'..'9']