https://wiki.haskell.org/api.php?action=feedcontributions&user=JeffHeard&feedformat=atomHaskellWiki - User contributions [en]2024-03-19T11:46:22ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Data.List.Split&diff=24732Data.List.Split2008-12-13T17:56:56Z<p>JeffHeard: </p>
<hr />
<div>A theoretical module which contains implementations/combinators for implementing every possible method of list-splitting known to man. This way no one has to argue about what the correct interface for split is, we can just have them all.<br />
<br />
Some possible ways to split a list, to get your creative juices flowing:<br />
* what to split on?<br />
** single-element separator<br />
** sublist separator<br />
** use a list of possible separators instead of just one<br />
** use a predicate on elements or sublists instead of giving explicit separators<br />
** use approximate matching?<br />
* how to split?<br />
** discard the separators<br />
** keep the separators with the preceding or following splits<br />
** keep the separators as their own separate pieces of the result list<br />
** what to do with separators at the beginning/end? create a blank split before/after, or not?<br />
<br />
Add your implementations below! Once we converge on something good we can upload it to hackage.<br />
<br />
<haskell><br />
{-# LANGUAGE ViewPatterns #-}<br />
<br />
import Data.List (unfoldr)<br />
<br />
<br />
-- intercalate :: [a] -> [[a]] -> [a]<br />
-- intercalate x [a,b,c,x,y,z] = [a,x,b,x,c,x,x,y,x,z,x]<br />
<br />
-- unintercalate :: [a] -> [a] -> [[a]]<br />
-- unintercalate x [a,x,b,x,c,x,x,y,x,z,x] = [a,b,c,[],y,z]<br />
<br />
-- unintercalate is the "inverse" of intercalate<br />
<br />
match [] string = Just string<br />
match (_:_) [] = Nothing<br />
match (p:ps) (q:qs) | p == q = match ps qs<br />
match (_:_) (_:_) | otherwise = Nothing<br />
<br />
chopWith delimiter (match delimiter -> Just tail) = return ([], tail)<br />
chopWith delimiter (c:cs) = chopWith delimiter cs >>= \(head, tail) -><br />
return (c:head, tail)<br />
chopWith delimiter [] = Nothing<br />
-- note: chopWith could be make 'more efficient' i.e. remove the >>=\-> bit<br />
-- by adding an accumulator<br />
<br />
<br />
unintercalate delimiter = unfoldr (chopWith delimiter)<br />
<br />
-- > unintercalate "x" "axbxcxxyxzx"<br />
-- ["a","b","c","","y","z"]<br />
<br />
splitOn :: (a -> Bool) -> [a] -> [[a]]<br />
splitOn _ [] = []<br />
splitOn f l@(x:xs)<br />
| f x = splitOn f xs<br />
| otherwise = let (h,t) = break f l in h:(splitOn f t)<br />
<br />
-- take the element who make predict true as delimiter<br />
-- > splitOn even [1,3,5,6,7,3,3,2,1,1,1]<br />
-- [[1,3,5],[7,3,3],[1,1,1]]<br />
<br />
-- | like String split, except for any element that obeys Eq<br />
splitEq :: Eq a -> [a] -> [[a]]<br />
splitEq _ [] = []<br />
splitEq e l@(x:xs)<br />
| e == x = splitOn e xs<br />
| otherwise = let (h,t) = break f l in h:(splitEq e t)<br />
<br />
</haskell></div>JeffHeard