module Data.Edison.Seq.JoinList (
Seq,
empty,singleton,lcons,rcons,append,lview,lhead,ltail,rview,rhead,rtail,
lheadM,ltailM,rheadM,rtailM,
null,size,concat,reverse,reverseOnto,fromList,toList,map,concatMap,
fold,fold',fold1,fold1',foldr,foldr',foldl,foldl',foldr1,foldr1',foldl1,foldl1',
reducer,reducer',reducel,reducel',reduce1,reduce1',
copy,inBounds,lookup,lookupM,lookupWithDefault,update,adjust,
mapWithIndex,foldrWithIndex,foldlWithIndex,
take,drop,splitAt,subseq,filter,partition,takeWhile,dropWhile,splitWhile,
zip,zip3,zipWith,zipWith3,unzip,unzip3,unzipWith,unzipWith3,
strict, strictWith,
structuralInvariant,
moduleName
) where
import Prelude hiding (concat,reverse,map,concatMap,foldr,foldl,foldr1,foldl1,
filter,takeWhile,dropWhile,lookup,take,drop,splitAt,
zip,zip3,zipWith,zipWith3,unzip,unzip3,null)
import qualified Data.Edison.Seq as S ( Sequence(..) )
import qualified Control.Applicative as App
import Data.Edison.Seq.Defaults
import Control.Monad
import Data.Monoid
import Data.Semigroup as SG
import Test.QuickCheck
moduleName :: String
empty :: Seq a
singleton :: a -> Seq a
lcons :: a -> Seq a -> Seq a
rcons :: a -> Seq a -> Seq a
append :: Seq a -> Seq a -> Seq a
lview :: (Monad m) => Seq a -> m (a, Seq a)
lhead :: Seq a -> a
lheadM :: (Monad m) => Seq a -> m a
ltail :: Seq a -> Seq a
ltailM :: (Monad m) => Seq a -> m (Seq a)
rview :: (Monad m) => Seq a -> m (a, Seq a)
rhead :: Seq a -> a
rheadM :: (Monad m) => Seq a -> m a
rtail :: Seq a -> Seq a
rtailM :: (Monad m) => Seq a -> m (Seq a)
null :: Seq a -> Bool
size :: Seq a -> Int
concat :: Seq (Seq a) -> Seq a
reverse :: Seq a -> Seq a
reverseOnto :: Seq a -> Seq a -> Seq a
fromList :: [a] -> Seq a
toList :: Seq a -> [a]
map :: (a -> b) -> Seq a -> Seq b
concatMap :: (a -> Seq b) -> Seq a -> Seq b
fold :: (a -> b -> b) -> b -> Seq a -> b
fold' :: (a -> b -> b) -> b -> Seq a -> b
fold1 :: (a -> a -> a) -> Seq a -> a
fold1' :: (a -> a -> a) -> Seq a -> a
foldr :: (a -> b -> b) -> b -> Seq a -> b
foldl :: (b -> a -> b) -> b -> Seq a -> b
foldr1 :: (a -> a -> a) -> Seq a -> a
foldl1 :: (a -> a -> a) -> Seq a -> a
reducer :: (a -> a -> a) -> a -> Seq a -> a
reducel :: (a -> a -> a) -> a -> Seq a -> a
reduce1 :: (a -> a -> a) -> Seq a -> a
foldr' :: (a -> b -> b) -> b -> Seq a -> b
foldl' :: (b -> a -> b) -> b -> Seq a -> b
foldr1' :: (a -> a -> a) -> Seq a -> a
foldl1' :: (a -> a -> a) -> Seq a -> a
reducer' :: (a -> a -> a) -> a -> Seq a -> a
reducel' :: (a -> a -> a) -> a -> Seq a -> a
reduce1' :: (a -> a -> a) -> Seq a -> a
copy :: Int -> a -> Seq a
inBounds :: Int -> Seq a -> Bool
lookup :: Int -> Seq a -> a
lookupM :: (Monad m) => Int -> Seq a -> m a
lookupWithDefault :: a -> Int -> Seq a -> a
update :: Int -> a -> Seq a -> Seq a
adjust :: (a -> a) -> Int -> Seq a -> Seq a
mapWithIndex :: (Int -> a -> b) -> Seq a -> Seq b
foldrWithIndex :: (Int -> a -> b -> b) -> b -> Seq a -> b
foldlWithIndex :: (b -> Int -> a -> b) -> b -> Seq a -> b
foldrWithIndex' :: (Int -> a -> b -> b) -> b -> Seq a -> b
foldlWithIndex' :: (b -> Int -> a -> b) -> b -> Seq a -> b
take :: Int -> Seq a -> Seq a
drop :: Int -> Seq a -> Seq a
splitAt :: Int -> Seq a -> (Seq a, Seq a)
subseq :: Int -> Int -> Seq a -> Seq a
filter :: (a -> Bool) -> Seq a -> Seq a
partition :: (a -> Bool) -> Seq a -> (Seq a, Seq a)
takeWhile :: (a -> Bool) -> Seq a -> Seq a
dropWhile :: (a -> Bool) -> Seq a -> Seq a
splitWhile :: (a -> Bool) -> Seq a -> (Seq a, Seq a)
zip :: Seq a -> Seq b -> Seq (a,b)
zip3 :: Seq a -> Seq b -> Seq c -> Seq (a,b,c)
zipWith :: (a -> b -> c) -> Seq a -> Seq b -> Seq c
zipWith3 :: (a -> b -> c -> d) -> Seq a -> Seq b -> Seq c -> Seq d
unzip :: Seq (a,b) -> (Seq a, Seq b)
unzip3 :: Seq (a,b,c) -> (Seq a, Seq b, Seq c)
unzipWith :: (a -> b) -> (a -> c) -> Seq a -> (Seq b, Seq c)
unzipWith3 :: (a -> b) -> (a -> c) -> (a -> d) -> Seq a -> (Seq b, Seq c, Seq d)
strict :: Seq a -> Seq a
strictWith :: (a -> b) -> Seq a -> Seq a
structuralInvariant :: Seq a -> Bool
moduleName = "Data.Edison.Seq.JoinList"
data Seq a = E | L a | A (Seq a) (Seq a)
half :: Int -> Int
half n = n `div` 2
empty = E
singleton = L
lcons x E = L x
lcons x xs = A (L x) xs
rcons x E = L x
rcons x xs = A xs (L x)
append E ys = ys
append xs E = xs
append xs ys = A xs ys
lview E = fail "JoinList.lview: empty sequence"
lview (L x) = return (x, E)
lview (A xs ys) = lvw xs ys
where lvw E _ = error "JoinList.lvw: bug"
lvw (L x) zs = return (x, zs)
lvw (A xs ys) zs = lvw xs (A ys zs)
lhead E = error "JoinList.lhead: empty sequence"
lhead (L x) = x
lhead (A xs _) = lhead xs
lheadM E = fail "JoinList.lheadM: empty sequence"
lheadM (L x) = return x
lheadM (A xs _) = lheadM xs
ltail E = error "JoinList.ltail: empty sequence"
ltail (L _) = E
ltail (A xs ys) = ltl xs ys
where ltl E _ = error "JoinList.ltl: bug"
ltl (L _) zs = zs
ltl (A xs ys) zs = ltl xs (A ys zs)
ltailM E = fail "JoinList.ltailM: empty sequence"
ltailM (L _) = return E
ltailM (A xs ys) = return (ltl xs ys)
where ltl E _ = error "JoinList.ltl: bug"
ltl (L _) zs = zs
ltl (A xs ys) zs = ltl xs (A ys zs)
rview E = fail "JoinLis.rview: empty sequence"
rview (L x) = return (x, E)
rview (A xs ys) = rvw xs ys
where rvw xs (A ys (A zs s)) = rvw (A xs (A ys zs)) s
rvw xs (A ys (L x)) = return (x, A xs ys)
rvw xs (L x) = return (x, xs)
rvw _ _ = error "JoinList.rvw: bug"
rhead E = error "JoinList.rhead: empty sequence"
rhead (L x) = x
rhead (A _ ys) = rhead ys
rheadM E = fail "JoinList.rheadM: empty sequence"
rheadM (L x) = return x
rheadM (A _ ys) = rheadM ys
rtail E = error "JoinList.rtail: empty sequence"
rtail (L _) = E
rtail (A xs ys) = rtl xs ys
where rtl xs (A ys (A zs s)) = A (A xs ys) (rtl zs s)
rtl xs (A ys (L _)) = A xs ys
rtl xs (L _) = xs
rtl _ _ = error "JoinList.rtl: bug"
rtailM E = fail "JoinList.rtailM: empty sequence"
rtailM (L _) = return E
rtailM (A xs ys) = return (rtl xs ys)
where rtl xs (A ys (A zs s)) = A (A xs ys) (rtl zs s)
rtl xs (A ys (L _)) = A xs ys
rtl xs (L _) = xs
rtl _ _ = error "JoinList.rtl: bug"
null E = True
null _ = False
size xs = sz xs (0::Int)
where sz E n = n
sz (L _) n = n + (1::Int)
sz (A xs ys) n = sz xs (sz ys n)
reverse (A xs ys) = A (reverse ys) (reverse xs)
reverse xs = xs
toList xs = tol xs []
where tol E rest = rest
tol (L x) rest = x:rest
tol (A xs ys) rest = tol xs (tol ys rest)
map _ E = E
map f (L x) = L (f x)
map f (A xs ys) = A (map f xs) (map f ys)
fold = foldr
fold' = foldr'
fold1 = fold1UsingFold
fold1' = fold1'UsingFold'
foldr _ e E = e
foldr f e (L x) = f x e
foldr f e (A xs ys) = foldr f (foldr f e ys) xs
foldr' _ e E = e
foldr' f e (L x) = f x $! e
foldr' f e (A xs ys) = (foldr' f $! (foldr' f e ys)) xs
foldl _ e E = e
foldl f e (L x) = f e x
foldl f e (A xs ys) = foldl f (foldl f e xs) ys
foldl' _ e E = e
foldl' f e (L x) = e `seq` f e x
foldl' f e (A xs ys) = e `seq` foldl' f (foldl' f e xs) ys
foldr1 _ E = error "JoinList.foldr1: empty sequence"
foldr1 _ (L x) = x
foldr1 f (A xs ys) = foldr f (foldr1 f ys) xs
foldr1' _ E = error "JoinLis.foldr1': empty sequence"
foldr1' _ (L x) = x
foldr1' f (A xs ys) = foldr' f (foldr1' f ys) xs
foldl1 _ E = error "JoinList.foldl1: empty sequence"
foldl1 _ (L x) = x
foldl1 f (A xs ys) = foldl f (foldl1 f xs) ys
foldl1' _ E = error "JoinList.foldl1': empty sequence"
foldl1' _ (L x) = x
foldl1' f (A xs ys) = foldl' f (foldl1' f xs) ys
copy n x
| n <= 0 = E
| otherwise = cpy n x
where cpy n x
| even n = let xs = cpy (half n) x
in A xs xs
| n == 1 = L x
| otherwise = let xs = cpy (half n) x
in A (L x) (A xs xs)
strict s@E = s
strict s@(L _) = s
strict s@(A l r) = strict l `seq` strict r `seq` s
strictWith _ s@E = s
strictWith f s@(L x) = f x `seq` s
strictWith f s@(A l _) = strictWith f l `seq` strictWith f l `seq` s
structuralInvariant E = True
structuralInvariant s = check s
where check E = False
check (L _) = True
check (A s1 s2) = check s1 && check s2
concat = concatUsingFoldr
reverseOnto = reverseOntoUsingReverse
fromList = fromListUsingCons
concatMap = concatMapUsingFoldr
reducer = reducerUsingReduce1
reducer' = reducer'UsingReduce1'
reducel = reducelUsingReduce1
reducel' = reducel'UsingReduce1'
reduce1 = reduce1UsingLists
reduce1' = reduce1'UsingLists
inBounds = inBoundsUsingDrop
lookup = lookupUsingDrop
lookupM = lookupMUsingDrop
lookupWithDefault = lookupWithDefaultUsingDrop
update = updateUsingSplitAt
adjust = adjustUsingSplitAt
mapWithIndex = mapWithIndexUsingLists
foldrWithIndex = foldrWithIndexUsingLists
foldrWithIndex' = foldrWithIndex'UsingLists
foldlWithIndex = foldlWithIndexUsingLists
foldlWithIndex' = foldlWithIndex'UsingLists
take = takeUsingLview
drop = dropUsingLtail
splitAt = splitAtUsingLview
subseq = subseqDefault
filter = filterUsingLview
partition = partitionUsingFoldr
takeWhile = takeWhileUsingLview
dropWhile = dropWhileUsingLview
splitWhile = splitWhileUsingLview
zip = zipUsingLview
zip3 = zip3UsingLview
zipWith = zipWithUsingLview
zipWith3 = zipWith3UsingLview
unzip = unzipUsingFoldr
unzip3 = unzip3UsingFoldr
unzipWith = unzipWithUsingFoldr
unzipWith3 = unzipWith3UsingFoldr
instance S.Sequence Seq where
{lcons = lcons; rcons = rcons;
lview = lview; lhead = lhead; ltail = ltail;
lheadM = lheadM; ltailM = ltailM; rheadM = rheadM; rtailM = rtailM;
rview = rview; rhead = rhead; rtail = rtail; null = null;
size = size; concat = concat; reverse = reverse;
reverseOnto = reverseOnto; fromList = fromList; toList = toList;
fold = fold; fold' = fold'; fold1 = fold1; fold1' = fold1';
foldr = foldr; foldr' = foldr'; foldl = foldl; foldl' = foldl';
foldr1 = foldr1; foldr1' = foldr1'; foldl1 = foldl1; foldl1' = foldl1';
reducer = reducer; reducer' = reducer'; reducel = reducel;
reducel' = reducel'; reduce1 = reduce1; reduce1' = reduce1';
copy = copy; inBounds = inBounds; lookup = lookup;
lookupM = lookupM; lookupWithDefault = lookupWithDefault;
update = update; adjust = adjust; mapWithIndex = mapWithIndex;
foldrWithIndex = foldrWithIndex; foldlWithIndex = foldlWithIndex;
foldrWithIndex' = foldrWithIndex'; foldlWithIndex' = foldlWithIndex';
take = take; drop = drop; splitAt = splitAt; subseq = subseq;
filter = filter; partition = partition; takeWhile = takeWhile;
dropWhile = dropWhile; splitWhile = splitWhile; zip = zip;
zip3 = zip3; zipWith = zipWith; zipWith3 = zipWith3; unzip = unzip;
unzip3 = unzip3; unzipWith = unzipWith; unzipWith3 = unzipWith3;
strict = strict; strictWith = strictWith;
structuralInvariant = structuralInvariant; instanceName _ = moduleName}
instance Functor Seq where
fmap = map
instance App.Alternative Seq where
empty = empty
(<|>) = append
instance App.Applicative Seq where
pure = return
x <*> y = do
x' <- x
y' <- y
return (x' y')
instance Monad Seq where
return = singleton
xs >>= k = concatMap k xs
instance MonadPlus Seq where
mplus = append
mzero = empty
instance Eq a => Eq (Seq a) where
xs == ys = toList xs == toList ys
instance Ord a => Ord (Seq a) where
compare = defaultCompare
instance Show a => Show (Seq a) where
showsPrec = showsPrecUsingToList
instance Read a => Read (Seq a) where
readsPrec = readsPrecUsingFromList
instance Arbitrary a => Arbitrary (Seq a) where
arbitrary = sized arbTree
where arbTree 0 = return E
arbTree 1 = liftM L arbitrary
arbTree n =
frequency [(1, liftM L arbitrary),
(4, liftM2 A (arbTree (n `div` 2))
(arbTree (n `div` 2)))]
instance CoArbitrary a => CoArbitrary (Seq a) where
coarbitrary E = variant 0
coarbitrary (L x) = variant 1 . coarbitrary x
coarbitrary (A xs ys) = variant 2 . coarbitrary xs . coarbitrary ys
instance Semigroup (Seq a) where
(<>) = append
instance Monoid (Seq a) where
mempty = empty
mappend = (SG.<>)