私は自分の質問について明確になったことを願っています!
どんな助けでもいただければ幸いです!
の関数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とのドキュメントfoldrはかなり明確ですが、.これまでに関数の合成に遭遇したことがない場合は、のドキュメントは少し簡潔です。
に与えられた引数toWordsはに供給されますfoldr cons ([], True)。.次に、から結果foldr cons ([], True)を取得し、にフィードしfstます。最後に、からの結果はそれ自体fstからの結果として使用され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これは、最初にそれを呼び出す方法を理解していることを確認した方が簡単な場合があります。