2012-07-13 66 views

回答

2

Prelude中的函數words將爲您篩選空格(根據所需類型查找函數的一種好方法是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爲一些很好的介紹性材料。

+0

哇,這太棒了!你能否確切地告訴我什麼時候我們應該按照這種方式編寫函數?他們對我來說很棘手。 – user1522145 2012-07-15 01:36:06

1

你想要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) 
0

當你在學習,這裏是浩從頭開始做。

import qualified Data.Set as S 

首先,該組字邊界的:(Data.Set.fromList需要的元素的列表; [Char]相同String,這就是爲什麼我們可以在這種情況下通過一個字符串)

wordBoundaries :: S.Set Char 
wordBoundaries = S.fromList " ." 

接下來,將字符串分割的話:

toWords :: String -> [String] 
toWords = fst . foldr cons ([], True) 
    where 

fstfoldr的文檔很清楚,但如果您以前沒有遇到過函數合成,那麼對於.有點簡潔。

給予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如何調用它,這可能會更容易。