module Data.Vector.Split.Internal
( split
, Splitter
, splitOn
, splitOneOf
, splitWhen
, endBy
, oneOf
, endByOneOf
, wordsBy
, linesBy
, onSublist
, whenElt
, dropDelims
, keepDelimsL
, keepDelimsR
, condense
, dropInitBlank
, dropInnerBlanks
, dropFinalBlank
, dropBlanks
, startsWith
, startsWithOneOf
, endsWith
, endsWithOneOf
) where
import Data.Vector.Generic (Vector)
import qualified Data.Vector.Generic as V
import qualified Data.Vector as BV
newtype Delimiter a = Delimiter (BV.Vector (a -> Bool))
matchDelim :: Vector v a => Delimiter a -> v a -> Maybe (v a, v a)
matchDelim :: forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> Maybe (v a, v a)
matchDelim (Delimiter Vector (a -> Bool)
ds) v a
xs = if Bool
match Bool -> Bool -> Bool
&& Bool
lengthOk then forall a. a -> Maybe a
Just (forall (v :: * -> *) a. Vector v a => Int -> v a -> (v a, v a)
V.splitAt (forall (v :: * -> *) a. Vector v a => v a -> Int
V.length Vector (a -> Bool)
ds) v a
xs) else forall a. Maybe a
Nothing
where match :: Bool
match = forall (v :: * -> *). Vector v Bool => v Bool -> Bool
V.and forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) a b c.
(Vector v a, Vector v b, Vector v c) =>
(a -> b -> c) -> v a -> v b -> v c
V.zipWith forall a b. (a -> b) -> a -> b
($) Vector (a -> Bool)
ds (forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert v a
xs)
lengthOk :: Bool
lengthOk = forall (v :: * -> *) a. Vector v a => v a -> Int
V.length Vector (a -> Bool)
ds forall a. Ord a => a -> a -> Bool
<= forall (v :: * -> *) a. Vector v a => v a -> Int
V.length v a
xs
data Chunk v a = Delim (v a) | Text (v a)
deriving (Int -> Chunk v a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (v :: * -> *) a. Show (v a) => Int -> Chunk v a -> ShowS
forall (v :: * -> *) a. Show (v a) => [Chunk v a] -> ShowS
forall (v :: * -> *) a. Show (v a) => Chunk v a -> String
showList :: [Chunk v a] -> ShowS
$cshowList :: forall (v :: * -> *) a. Show (v a) => [Chunk v a] -> ShowS
show :: Chunk v a -> String
$cshow :: forall (v :: * -> *) a. Show (v a) => Chunk v a -> String
showsPrec :: Int -> Chunk v a -> ShowS
$cshowsPrec :: forall (v :: * -> *) a. Show (v a) => Int -> Chunk v a -> ShowS
Show, Chunk v a -> Chunk v a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (v :: * -> *) a. Eq (v a) => Chunk v a -> Chunk v a -> Bool
/= :: Chunk v a -> Chunk v a -> Bool
$c/= :: forall (v :: * -> *) a. Eq (v a) => Chunk v a -> Chunk v a -> Bool
== :: Chunk v a -> Chunk v a -> Bool
$c== :: forall (v :: * -> *) a. Eq (v a) => Chunk v a -> Chunk v a -> Bool
Eq)
type SplitList v a = [Chunk v a]
type Splitter v a = v a -> SplitList v a
toSplitList :: Vector v a => Delimiter a -> v a -> SplitList v a
toSplitList :: forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> SplitList v a
toSplitList Delimiter a
d v a
v = Int -> [Chunk v a]
go Int
0
where go :: Int -> [Chunk v a]
go Int
i | Int
i forall a. Ord a => a -> a -> Bool
< forall (v :: * -> *) a. Vector v a => v a -> Int
V.length v a
v = case forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> Maybe (v a, v a)
matchDelim Delimiter a
d (forall (v :: * -> *) a. Vector v a => Int -> v a -> v a
V.drop Int
i v a
v) of
Just (v a
l,v a
r) -> forall (v :: * -> *) a. v a -> Chunk v a
Text (forall (v :: * -> *) a. Vector v a => Int -> v a -> v a
V.take Int
i v a
v) forall a. a -> [a] -> [a]
: forall (v :: * -> *) a. v a -> Chunk v a
Delim v a
l forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> SplitList v a
toSplitList Delimiter a
d v a
r
Maybe (v a, v a)
Nothing -> Int -> [Chunk v a]
go (Int
iforall a. Num a => a -> a -> a
+Int
1)
| Bool
otherwise = [forall (v :: * -> *) a. v a -> Chunk v a
Text v a
v]
split :: Vector v a => Splitter v a -> v a -> [v a]
split :: forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split Splitter v a
s v a
v = forall a b. (a -> b) -> [a] -> [b]
map forall {v :: * -> *} {a}. Chunk v a -> v a
go forall a b. (a -> b) -> a -> b
$ Splitter v a
s v a
v
where go :: Chunk v a -> v a
go (Text v a
t) = v a
t
go (Delim v a
d) = v a
d
splitOn :: (Vector v a, Eq a) => v a -> v a -> [v a]
splitOn :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a -> [v a]
splitOn v a
xs = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
onSublist v a
xs)
splitOneOf :: (Vector v a, Eq a) => v a -> v a -> [v a]
splitOneOf :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a -> [v a]
splitOneOf v a
xs = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
oneOf v a
xs)
splitWhen :: (Vector v a) => (a -> Bool) -> v a -> [v a]
splitWhen :: forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> [v a]
splitWhen a -> Bool
p = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Vector v a => (a -> Bool) -> Splitter v a
whenElt a -> Bool
p)
endBy :: (Vector v a, Eq a) => v a -> v a -> [v a]
endBy :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a -> [v a]
endBy v a
xs = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
onSublist v a
xs)
oneOf :: (Vector v a, Eq a) => v a -> Splitter v a
oneOf :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
oneOf v a
xs = forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> SplitList v a
toSplitList Delimiter a
delim
where delim :: Delimiter a
delim = forall a. Vector (a -> Bool) -> Delimiter a
Delimiter (forall a. a -> Vector a
BV.singleton (forall (v :: * -> *) a. (Vector v a, Eq a) => a -> v a -> Bool
`V.elem` v a
xs))
endByOneOf :: (Vector v a, Eq a) => v a -> v a -> [v a]
endByOneOf :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a -> [v a]
endByOneOf v a
xs = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
oneOf v a
xs)
wordsBy :: Vector v a => (a -> Bool) -> v a -> [v a]
wordsBy :: forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> [v a]
wordsBy a -> Bool
p = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropBlanks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Vector v a => (a -> Bool) -> Splitter v a
whenElt a -> Bool
p)
linesBy :: Vector v a => (a -> Bool) -> v a -> [v a]
linesBy :: forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> [v a]
linesBy a -> Bool
p = forall (v :: * -> *) a. Vector v a => Splitter v a -> v a -> [v a]
split (forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Vector v a => (a -> Bool) -> Splitter v a
whenElt a -> Bool
p)
onSublist :: (Vector v a, Eq a) => v a -> Splitter v a
onSublist :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
onSublist v a
xs = forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> SplitList v a
toSplitList Delimiter a
delim
where delim :: Delimiter a
delim = forall a. Vector (a -> Bool) -> Delimiter a
Delimiter (forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(a -> b) -> v a -> v b
V.map forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert forall a b. (a -> b) -> a -> b
$ v a
xs)
whenElt :: (Vector v a) => (a -> Bool) -> Splitter v a
whenElt :: forall (v :: * -> *) a. Vector v a => (a -> Bool) -> Splitter v a
whenElt a -> Bool
p = forall (v :: * -> *) a.
Vector v a =>
Delimiter a -> v a -> SplitList v a
toSplitList Delimiter a
delim
where delim :: Delimiter a
delim = forall a. Vector (a -> Bool) -> Delimiter a
Delimiter (forall (v :: * -> *) a. Vector v a => a -> v a
V.singleton a -> Bool
p)
dropDelims :: Vector v a => SplitList v a -> SplitList v a
dropDelims :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropDelims = forall a. (a -> Bool) -> [a] -> [a]
filter forall {v :: * -> *} {a}. Chunk v a -> Bool
go
where go :: Chunk v a -> Bool
go (Delim v a
_) = Bool
False
go (Text v a
_ ) = Bool
True
keepDelimsL :: Vector v a => SplitList v a -> SplitList v a
keepDelimsL :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsL (Delim v a
d : Text v a
t : [Chunk v a]
rst) = forall (v :: * -> *) a. v a -> Chunk v a
Text (v a
d forall (v :: * -> *) a. Vector v a => v a -> v a -> v a
V.++ v a
t) forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsL [Chunk v a]
rst
keepDelimsL (Chunk v a
rs : [Chunk v a]
rst) = Chunk v a
rs forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsL [Chunk v a]
rst
keepDelimsL [] = []
keepDelimsR :: Vector v a => SplitList v a -> SplitList v a
keepDelimsR :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsR (Text v a
t : Delim v a
d : [Chunk v a]
rst) = forall (v :: * -> *) a. v a -> Chunk v a
Text (v a
t forall (v :: * -> *) a. Vector v a => v a -> v a -> v a
V.++ v a
d) forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsR [Chunk v a]
rst
keepDelimsR (Chunk v a
rs : [Chunk v a]
rst) = Chunk v a
rs forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsR [Chunk v a]
rst
keepDelimsR [] = []
condense :: Vector v a => SplitList v a -> SplitList v a
condense :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
condense (Delim v a
a : Delim v a
b : [Chunk v a]
rst) = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
condense (forall (v :: * -> *) a. v a -> Chunk v a
Delim (v a
a forall (v :: * -> *) a. Vector v a => v a -> v a -> v a
V.++ v a
b) forall a. a -> [a] -> [a]
: [Chunk v a]
rst)
condense (Delim v a
a : Text v a
t : Delim v a
b : [Chunk v a]
rst) | forall (v :: * -> *) a. Vector v a => v a -> Bool
V.null v a
t = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
condense (forall (v :: * -> *) a. v a -> Chunk v a
Delim (v a
a forall (v :: * -> *) a. Vector v a => v a -> v a -> v a
V.++ v a
b) forall a. a -> [a] -> [a]
: [Chunk v a]
rst)
condense (Chunk v a
t : [Chunk v a]
rst) = Chunk v a
t forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
condense [Chunk v a]
rst
condense [] = []
dropInitBlank :: Vector v a => SplitList v a -> SplitList v a
dropInitBlank :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInitBlank (Text v a
t : [Chunk v a]
rst) | forall (v :: * -> *) a. Vector v a => v a -> Bool
V.null v a
t = [Chunk v a]
rst
dropInitBlank [Chunk v a]
rst = [Chunk v a]
rst
dropFinalBlank :: Vector v a => SplitList v a -> SplitList v a
dropFinalBlank :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank [Text v a
t] | forall (v :: * -> *) a. Vector v a => v a -> Bool
V.null v a
t = []
dropFinalBlank (Chunk v a
rs : [Chunk v a]
rst) = Chunk v a
rs forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank [Chunk v a]
rst
dropFinalBlank [] = []
dropInnerBlanks :: Vector v a => SplitList v a -> SplitList v a
dropInnerBlanks :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInnerBlanks (Text v a
a : [Chunk v a]
rst) = forall (v :: * -> *) a. v a -> Chunk v a
Text v a
a forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInnerBlanksGo [Chunk v a]
rst
dropInnerBlanks [Chunk v a]
rst = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInnerBlanksGo [Chunk v a]
rst
dropInnerBlanksGo :: Vector v a => [Chunk v a] -> [Chunk v a]
dropInnerBlanksGo :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInnerBlanksGo [Text v a
a] = [forall (v :: * -> *) a. v a -> Chunk v a
Text v a
a]
dropInnerBlanksGo (Text v a
a : [Chunk v a]
rst) | forall (v :: * -> *) a. Vector v a => v a -> Bool
V.null v a
a = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInnerBlanksGo [Chunk v a]
rst
dropInnerBlanksGo (Chunk v a
chunk : [Chunk v a]
rst) = Chunk v a
chunk forall a. a -> [a] -> [a]
: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInnerBlanksGo [Chunk v a]
rst
dropInnerBlanksGo [] = []
dropBlanks :: Vector v a => SplitList v a -> SplitList v a
dropBlanks :: forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropBlanks = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
condense forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter forall {v :: * -> *} {a}. Vector v a => Chunk v a -> Bool
go
where go :: Chunk v a -> Bool
go (Text v a
t) | forall (v :: * -> *) a. Vector v a => v a -> Bool
V.null v a
t = Bool
False
go Chunk v a
_ = Bool
True
startsWith :: (Vector v a, Eq a) => v a -> Splitter v a
startsWith :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
startsWith v a
xs = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInitBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsL forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
onSublist v a
xs
startsWithOneOf :: (Vector v a, Eq a) => v a -> Splitter v a
startsWithOneOf :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
startsWithOneOf v a
xs = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropInitBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsL forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
oneOf v a
xs
endsWith :: (Vector v a, Eq a) => v a -> Splitter v a
endsWith :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
endsWith v a
xs = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsR forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
onSublist v a
xs
endsWithOneOf :: (Vector v a, Eq a) => v a -> Splitter v a
endsWithOneOf :: forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
endsWithOneOf v a
xs = forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
dropFinalBlank forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
Vector v a =>
SplitList v a -> SplitList v a
keepDelimsR forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> Splitter v a
oneOf v a
xs