>>> splitOn "\r\n" "a\r\nb\r\nd\r\ne" ["a","b","d","e"]
>>> splitOn "aaa" "aaaXaaaXaaaXaaa" ["","X","X","X",""]
>>> splitOn "x" "x" ["",""]and
intercalate s . splitOn s == id splitOn (singleton c) == split (==c)(Note: the string s to split on above cannot be empty.) In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).
splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"] splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""] splitOn "x" "x" == ["",""]and
intercalate s . splitOn s == id splitOn (singleton c) == split (==c)(Note: the string s to split on above cannot be empty.) This function is strict in its first argument, and lazy in its second. In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).
>>> splitOn ":" "12:35:07" ["12","35","07"]
>>> splitOn "x" "axbxc" ["a","b","c"]
>>> splitOn "x" "axbxcx" ["a","b","c",""]
>>> splitOn ".." "a..b...c....d.." ["a","b",".c","","d",""]In some parsing combinator frameworks this is also known as sepBy. Note that this is the right inverse of the intercalate function from Data.List, that is,
intercalate x . splitOn x === idsplitOn x . intercalate x is the identity on certain lists, but it is tricky to state the precise conditions under which this holds. (For example, it is not enough to say that x does not occur in any elements of the input list. Working out why is left as an exercise for the reader.)
splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"] splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""] splitOn "x" "x" == ["",""] splitOn "x" "" == [""] \s x -> s /= "" ==> intercalate s (splitOn s x) == x \c x -> splitOn [c] x == split (==c) x
ghci> Streams.fromList ["the quick br", "own fox"::ByteString] >>= Streams.splitOn (== ' ') >>= Streams.toList ["the","quick","brown","","fox"]
splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"] splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""] splitOn "x" "x" == ["",""]and
intercalate s . splitOn s == id splitOn (singleton c) == split (==c)(Note: the string s to split on above cannot be empty.) This function is strict in its first argument, and lazy in its second. In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).
>>> splitOn "\r\n" "a\r\nb\r\nd\r\ne" ["a","b","d","e"]
>>> splitOn "aaa" "aaaXaaaXaaaXaaa" ["","X","X","X",""]
>>> splitOn "x" "x" ["",""]and
intercalate s . splitOn s == id splitOn (singleton c) == split (==c)(Note: the string s to split on above cannot be empty.) In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).
splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"] splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""] splitOn "x" "x" == ["",""]and
intercalate s . splitOn s == id splitOn (singleton c) == split (==c)(Note: the string s to split on above cannot be empty.) In (unlikely) bad cases, this function's time complexity degrades towards O(n*m).
>>> splitOn' p xs = Stream.toList $ Stream.splitOn p Fold.toList (Stream.fromList xs) >>> splitOn' (== '.') "a.b" ["a","b"]An empty stream is folded to the default value of the fold:
>>> splitOn' (== '.') "" [""]If one or both sides of the separator are missing then the empty segment on that side is folded to the default output of the fold:
>>> splitOn' (== '.') "." ["",""]
>>> splitOn' (== '.') ".a" ["","a"]
>>> splitOn' (== '.') "a." ["a",""]
>>> splitOn' (== '.') "a..b" ["a","","b"]splitOn is an inverse of intercalating single element:
Stream.intercalate (Stream.fromPure '.') Unfold.fromList . Stream.splitOn (== '.') Fold.toList === idAssuming the input stream does not contain the separator:
Stream.splitOn (== '.') Fold.toList . Stream.intercalate (Stream.fromPure '.') Unfold.fromList === id
>>> splitOn' p xs = Stream.fold Fold.toList $ Stream.splitOn p Fold.toList (Stream.fromList xs) >>> splitOn' (== '.') "a.b" ["a","b"]An empty stream is folded to the default value of the fold:
>>> splitOn' (== '.') "" [""]If one or both sides of the separator are missing then the empty segment on that side is folded to the default output of the fold:
>>> splitOn' (== '.') "." ["",""]
>>> splitOn' (== '.') ".a" ["","a"]
>>> splitOn' (== '.') "a." ["a",""]
>>> splitOn' (== '.') "a..b" ["a","","b"]splitOn is an inverse of intercalating single element:
Stream.intercalate (Stream.fromPure '.') Unfold.fromList . Stream.splitOn (== '.') Fold.toList === idAssuming the input stream does not contain the separator:
Stream.splitOn (== '.') Fold.toList . Stream.intercalate (Stream.fromPure '.') Unfold.fromList === id
splitOn (== ',') "," == ["",""] splitOn (== ',') ",abc," == ["","abc",""] splitOn (== ':') "abc" == ["abc"] splitOn (== ':') "abc::def" == ["abc","","def"] splitOn (== ':') "::abc::def" == ["","","abc","","def"]
>>> splitOn (BV.fromList "..") (BV.fromList "a..b...c....d..") ["a","b",".c","","d",""]In some parsing combinator frameworks this is also known as sepBy. Note that this is the right inverse of the intercalate function from Data.List, that is,
> \xs -> (intercalate xs . splitOn xs) === idsplitOn x . intercalate x is the identity on certain lists, but it is tricky to state the precise conditions under which this holds. (For example, it is not enough to say that x does not occur in any elements of the input list. Working out why is left as an exercise for the reader.)