我希望我清楚我的问题!
任何帮助,将不胜感激!
words
中的函数Prelude
将为您过滤掉空格(按所需类型查找函数的好方法是Hoogle)。
Prelude> :t words
words :: String -> [String]
您只需要使用适当的过滤器来组合它,该过滤器使用Set
. 这是一个非常基本的:
import Data.Set (Set, fromList, notMember)
parser :: String -> [String]
parser = words . filter (`notMember` delims)
where delims = fromList ".,!?"
parser "yeah. what?"
将返回["yeah", "what"]
。
查看Learn You A Haskell以获得一些很好的介绍性材料。
您需要Data.List.Split,它涵盖了绝大多数拆分用例。
对于您的示例,只需使用:
splitOneOf ".,!?"
如果你想摆脱连续分隔符之间的“空词”,只需使用:
filter (not . null) . splitOneOf ".,!?"
如果您希望这些分隔符来自您已经存储它们的集合,那么只需使用:
import qualified Data.Set as S
s :: S.Set Char
split = filter (not . null) . splitOneOf (S.toList s)
在您学习的过程中,以下是从头开始的方法。
import qualified Data.Set as S
首先,单词边界的集合:
wordBoundaries :: S.Set Char
wordBoundaries = S.fromList " ."
(Data.Set.fromList
接受一个元素列表;[Char]
与 相同String
,这就是为什么我们可以在这种情况下传递一个字符串。)
接下来,将字符串拆分为单词:
toWords :: String -> [String]
toWords = fst . foldr cons ([], True)
where
fst
and的文档foldr
非常清楚,但是.
如果您以前没有遇到过函数组合,那么 for 的文档就有点简洁了。
给定的参数toWords
被馈送到foldr cons ([], True)
. .
然后从中获取结果foldr cons ([], True)
并将其提供给fst
. 最后,结果 fromfst
用作toWords
自身的结果。
我们还需要定义cons
:
cons :: Char -> ([String], Bool) -> ([String], Bool)
cons ch (words, startNew)
| S.member ch wordBoundaries = ( words, True)
| startNew = ([ch] : words, False)
cons ch (word : words, _) = ((ch : word) : words, False)
家庭作业:弄清楚它是做什么cons
的以及它是如何工作的。foldr
如果您首先确保您了解如何调用它,这可能会更容易。