2011-11-25 74 views
2

我在無關項目中第二次寫入以下函數(首先是XML處理,現在是自定義命令行標記處理),並且我有一種感覺,它應該存在於某個庫中,我無法找到它。它將列表元素分組,每個組從謂詞爲真的元素開始。更簡單的groupStartBy函數?

任何更簡單的方法來做到這一點?

groupStartBy :: (a -> Bool) -> [a] -> [[a]] 
groupStartBy pred xs = reverse $ map reverse $ foldl' step [] xs 
    where 
    step as x | pred x = [x]:as 
    step (a:as) x = (x:a):as 
    step [] x = [[x]] 

回答

5

您可以使用groupBy做到這一點:

import Data.List (groupBy) 

groupStartBy :: (a -> Bool) -> [a] -> [[a]] 
groupStartBy pred = groupBy (const (not . pred)) 
-- or in point free style: groupStartBy = groupBy . const . (not .) 
+0

尼斯和簡單的選擇! –

1

split package可以在這裏非常有用。我還沒有找到與你的功能具有完全相同功能的東西,但是如果你玩弄一些基本功能,我敢打賭你可以得到你想要的東西。 splitWhen是相似的,但會丟棄滿足謂詞的元素。 split . whenElt稍微接近一點,但將謂詞元素分隔爲新列表的不同元素。

0

也許是這樣的:

groupStartBy :: (a -> Bool) -> [a] -> [[a]] 
groupStartBy f = split (dropInitBlank . keepDelimsL . whenElt $ f) 

,如果我理解正確的你。 split,dropInitBlank,keepDelimsLwhenElt來自Data.List.Split