关于 filter:Haskell : 过滤字符串列表

Haskell : Filtering a list of strings

我有一个要过滤的字符串列表。我的谓词是字符串应该以大写字母开头。

例如。当我运行 onlyLowercase ["boy","girl","Hi"]

它应该给我一个 ["boy","girl"]

的列表

我可以使用模式匹配和守卫来做到这一点,但我使用的是 learnyouahaskell (http://learnyouahaskell.com) 书,我遇到了关于高阶函数的主题。我阅读了有关过滤器功能的信息,并认为它可以用更少的代码行来实现我想要做的事情。

使用模式匹配/守卫(这很好,解决了我的问题)

1
2
3
4
5
onlyLowercase :: [[Char]] -> [[Char]]
onlyLowercase [] = []
onlyLowercase (x:xs)
  | isLower (head x) = x : onlyLowercase xs  
  | otherwise = onlyLowercase xs

使用过滤功能

1
2
3
onlyLowercase2 :: [String] -> [String]
onlyLowercase2 [] = []
onlyLowercase2 (x:xs) = filter isLower x : onlyLowercase2 xs

不幸的是,当我运行 onlyLowercase2 ["boy","girl","Hi"] 时,
我得到 ["boy","girl","i"].

的列表

我想知道是否有一种方法可以使用字符串中的第一个字符过滤字符串列表(无需创建任何可以检查字符串并在第一个字母为小写时返回 true 的辅助函数)。

我也尝试过使用

1
 onlyLowercase2 (x:xs) = filter (isLower head x) : onlyLowercase2 xs

但这甚至没有编译。基本上,我只是想弄清楚如何在列表列表中使用过滤器功能。提前感谢您提供的任何帮助。


感谢 Willem Van Onsem 建议使用 lambda 表达式作为过滤函数,我进一步阅读并提出了这个 2 行解决方案。

1
2
onlyLowercase2 :: [String] -> [String]
onlyLowercase2 = filter (\\st-> ("" /= st) && (isLower $ head st))

不确定它是否完美,但至少它可以工作。


使用 Data.ListData.Char:

1
2
3
4
5
import Data.List
import Data.Char

onlyLowerCase :: [String] -> [String]
onlyLowerCase = filter (all isLower)

我使用 all 函数来检查列表的 all 元素是否满足谓词。在这种情况下,如果 String 中的所有字母都是小写,则 all isLower 将返回 true。然后只是 filterStrings 都是小写的。 Haskell 报告对 ListChar 函数以及其他有用的库有很好的参考。