--
-- list like wrappers for abstract streams
--
-- These specify the versions used when fusion occurs.
--
-- So we can check our stream implementations, which are only used when
-- fusion happens, are fast.
--
module Bench.StreamList where
import Prelude
import qualified Prelude
import Properties.Utils
import qualified Data.Stream as Stream
-- * Basic interface
cons :: a -> [a] -> [a]
snoc :: [a] -> a -> [a]
append :: [a] -> [a] -> [a]
head :: [a] -> a
last :: [a] -> a
tail :: [a] -> [a]
init :: [a] -> [a]
null :: [a] -> Bool
length :: [a] -> Int
-- * List transformations
map :: (a -> b) -> [a] -> [b]
--reverse :: [a] -> [a]
intersperse :: a -> [a] -> [a]
intercalate :: [a] -> [[a]] -> [a]
--transpose :: [[a]] -> [[a]]
-- * Reducing lists (folds)
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl' :: (b -> a -> b) -> b -> [a] -> b
foldl1 :: (a -> a -> a) -> [a] -> a
foldl1' :: (a -> a -> a) -> [a] -> a
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr1 :: (a -> a -> a) -> [a] -> a
-- ** Special folds
concat :: [[a]] -> [a]
concatMap :: (a -> [b]) -> [a] -> [b]
and :: [Bool] -> Bool
or :: [Bool] -> Bool
any :: (a -> Bool) -> [a] -> Bool
all :: (a -> Bool) -> [a] -> Bool
sum :: [N] -> N
product :: [N] -> N
maximum :: Ord a => [a] -> a
minimum :: Ord a => [a] -> a
-- * Building lists
-- ** Scans
scanl :: (a -> b -> a) -> a -> [b] -> [a]
scanl1 :: (a -> a -> a) -> [a] -> [a]
{-
scanr :: (a -> b -> b) -> b -> [a] -> [b]
scanr1 :: (a -> a -> a) -> [a] -> [a]
-- ** Accumulating maps
mapAccumL :: (c -> a -> (c, b)) -> c -> [a] -> (c, [b])
mapAccumR :: (c -> a -> (c, b)) -> c -> [a] -> (c, [b])
-}
-- ** Infinite lists
iterate :: (a -> a) -> a -> [a]
repeat :: a -> [a]
replicate :: Int -> a -> [a]
cycle :: [a] -> [a]
-- ** Unfolding
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
-- * Sublists
-- ** Extracting sublists
take :: Int -> [a] -> [a]
drop :: Int -> [a] -> [a]
splitAt :: Int -> [a] -> ([a], [a])
takeWhile :: (a -> Bool) -> [a] -> [a]
dropWhile :: (a -> Bool) -> [a] -> [a]
{-
span :: (a -> Bool) -> [a] -> ([a], [a])
break :: (a -> Bool) -> [a] -> ([a], [a])
group :: [a] -> [[a]]
inits :: [a] -> [[a]]
tails :: [a] -> [[a]]
-}
-- * Predicates
isPrefixOf :: Eq a => [a] -> [a] -> Bool
{-
isSuffixOf :: [a] -> [a] -> Bool
isInfixOf :: [a] -> [a] -> Bool
-}
-- * Searching lists
-- ** Searching by equality
elem :: Eq a => a -> [a] -> Bool
--notElem :: Eq a => a -> [a] -> Bool
lookup :: Eq a => a -> [(a, b)] -> Maybe b
-- ** Searching with a predicate
find :: (a -> Bool) -> [a] -> Maybe a
filter :: (a -> Bool) -> [a] -> [a]
--partition :: (a -> Bool) -> [a] -> ([a], [a])
-- * Indexing lists
(!!) :: [a] -> Int -> a
findIndex :: (a -> Bool) -> [a] -> Maybe Int
elemIndex :: Eq a => a -> [a] -> Maybe Int
elemIndices :: Eq a => a -> [a] -> [Int]
findIndices :: (a -> Bool) -> [a] -> [Int]
-- * Zipping and unzipping lists
zip :: [a] -> [b] -> [(a, b)]
zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
{-
zip4 :: [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a, b, c, d, e)]
zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]
zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a, b, c, d, e, f, g)]
-}
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
{-
zipWith4 :: (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
zipWith5 :: (a -> b -> c -> d -> e -> f) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f]
zipWith6 :: (a -> b -> c -> d -> e -> f -> g) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g]
zipWith7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [h]
-}
unzip :: [(a, b)] -> ([a], [b])
{-
unzip3 :: [(a, b, c)] -> ([a], [b], [c])
unzip4 :: [(a, b, c, d)] -> ([a], [b], [c], [d])
unzip5 :: [(a, b, c, d, e)] -> ([a], [b], [c], [d], [e])
unzip6 :: [(a, b, c, d, e, f)] -> ([a], [b], [c], [d], [e], [f])
unzip7 :: [(a, b, c, d, e, f, g)] -> ([a], [b], [c], [d], [e], [f], [g])
-}
-- * Special lists
-- ** Functions on strings
{-
unlines :: [String] -> String
lines :: String -> [String]
-}
{-
words :: String -> [String]
unwords :: [String] -> String
-- ** \"Set\" operations
nub :: [a] -> [a]
delete :: a -> [a] -> [a]
(\\) :: [a] -> [a] -> [a]
union :: [a] -> [a] -> [a]
intersect :: [a] -> [a] -> [a]
-- ** Ordered lists
sort :: [a] -> [a]
insert :: a -> [a] -> [a]
-- * Generalized functions
-- ** The \"By\" operations
-- *** User-supplied equality (replacing an Eq context)
nubBy :: (a -> a -> Bool) -> [a] -> [a]
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
-}
-- *** User-supplied comparison (replacing an Ord context)
insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
{-
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
-}
maximumBy :: (a -> a -> Ordering) -> [a] -> a
minimumBy :: (a -> a -> Ordering) -> [a] -> a
-- * The \"generic\" operations
genericLength :: [a] -> I
genericTake :: I -> [a] -> [a]
genericDrop :: I -> [a] -> [a]
genericIndex :: [a] -> I -> a
genericSplitAt :: I -> [a] -> ([a], [a])
genericReplicate :: I -> a -> [a]
s = Stream.stream
u = Stream.unstream
-- * Basic interface
cons = \x xs -> u $ Stream.cons x (s xs)
snoc = \xs x -> u $ Stream.snoc (s xs) x
append = \xs ys -> u $ Stream.append (s xs) (s ys)
head = \xs -> Stream.head (s xs)
last = \xs -> Stream.last (s xs)
tail = \xs -> u $ Stream.tail (s xs)
init = \xs -> u $ Stream.init (s xs)
null = \xs -> Stream.null (s xs)
length = \xs -> Stream.length (s xs)
-- * List transformations
map = \f xs -> u $ Stream.map f (s xs)
--reverse = Stream.reverse
intersperse = \sep xs -> u $ Stream.intersperse sep (s xs)
intercalate = \sep xs -> Stream.concat (Stream.intersperse sep(s xs))
--transpose = Stream.transpose
-- * Reducing lists (folds)
foldl = \f z xs -> Stream.foldl f z (s xs)
foldl' = \f z xs -> Stream.foldl' f z (s xs)
foldl1 = \f xs -> Stream.foldl1 f (s xs)
foldl1' = \f xs -> Stream.foldl1' f (s xs)
foldr = \f z xs -> Stream.foldr f z (s xs)
foldr1 = \f xs -> Stream.foldr1 f (s xs)
-- ** Special folds
concat = \ xs -> Stream.concat (s xs)
-- concatMap :: (a -> Stream b) -> Stream a -> Stream b
concatMap = \f xs -> u $ Stream.concatMap (s . f) (s xs)
and = \ xs -> Stream.and (s xs)
or = \ xs -> Stream.or (s xs)
any = \f xs -> Stream.any f (s xs)
all = \f xs -> Stream.all f (s xs)
sum = \ xs -> Stream.sum (s xs)
product = \ xs -> Stream.product (s xs)
maximum = \ xs -> Stream.maximum (s xs)
{-# INLINE maximum #-}
minimum = \ xs -> Stream.minimum (s xs)
{-# INLINE minimum #-}
-- * Building lists
-- ** Scans
scanl = \f z xs -> u (Stream.scanl f z (Stream.snoc (s xs) bottom))
where
bottom :: a
bottom = error "StreamProperties.bottom"
scanl1 = \f xs -> u (Stream.scanl1 f (Stream.snoc (s xs) bottom))
where
bottom :: a
bottom = error "StreamProperties.bottom"
{-
scanr = \f z xs -> u (Stream.scanr f z (Stream.cons bottom (s xs)))
where
bottom :: a
bottom = error "StreamProperties.bottom"
-}
{-
scanr1 = Stream.scanr1
-- ** Accumulating maps
mapAccumL = Stream.mapAccumL
mapAccumR = Stream.mapAccumR
-}
-- ** Infinite lists
iterate = \f x -> u $ Stream.iterate f x
repeat = \ x -> u $ Stream.repeat x
replicate = \n x -> u $ Stream.replicate n x
cycle = \ xs -> u $ Stream.cycle (s xs)
-- ** Unfolding
unfoldr = \f x -> u $ Stream.unfoldr f x
-- * Sublists
-- ** Extracting sublists
take = \n xs -> u $ Stream.take n (s xs)
drop = \n xs -> u $ Stream.drop n (s xs)
splitAt = \n xs -> Stream.splitAt n (s xs)
takeWhile = \f xs -> u $ Stream.takeWhile f (s xs)
dropWhile = \f xs -> u $ Stream.dropWhile f (s xs)
{-
span = Stream.span
break = Stream.break
group = Stream.group
inits = Stream.inits
tails = Stream.tails
-}
-- * Predicates
isPrefixOf = \xs ys -> Stream.isPrefixOf (s xs) (s ys)
{-
isSuffixOf = Stream.isSuffixOf
isInfixOf = Stream.isInfixOf
-}
-- * Searching lists
-- ** Searching by equality
elem = \key xs -> Stream.elem key (s xs)
--notElem = Stream.notElem
lookup = \key xs -> Stream.lookup key (s xs)
-- ** Searching with a predicate
find = \p xs -> Stream.find p (s xs)
filter = \p xs -> u $ Stream.filter p (s xs)
--partition = Stream.partition
-- * Indexing lists
(!!) = \xs n -> Stream.index (Stream.stream xs) n
--Wirdness: Stream.index needs to be eta-expanded and fully applied for the
-- code to be any good
findIndex = \f xs -> Stream.findIndex f (s xs)
findIndices = \p xs -> u (Stream.findIndices p (s xs))
elemIndex = \x xs -> Stream.findIndex (x==) (s xs)
elemIndices = \x xs -> u (Stream.findIndices (x==) (s xs))
{-# INLINE elemIndex #-}
{-# INLINE elemIndices #-}
-- * Zipping and unzipping lists
zip = \xs ys -> u (Stream.zip (s xs) (s ys))
zip3 = \xs ys zs -> u (Stream.zip3 (s xs) (s ys) (s zs))
zipWith = \f xs ys -> u (Stream.zipWith f (s xs) (s ys))
zipWith3 = \f xs ys zs -> u (Stream.zipWith3 f (s xs) (s ys) (s zs))
unzip = Stream.unzip . s
{-
zip4 = Stream.zip4
zip5 = Stream.zip5
zip6 = Stream.zip6
zip7 = Stream.zip7
zipWith4 = Stream.zipWith4
zipWith5 = Stream.zipWith5
zipWith6 = Stream.zipWith6
zipWith7 = Stream.zipWith7
unzip3 = Stream.unzip3
unzip4 = Stream.unzip4
unzip5 = Stream.unzip5
unzip6 = Stream.unzip6
unzip7 = Stream.unzip7
-}
-- * Special lists
-- ** Functions on strings
{-
unlines = \xs -> Stream.concatMap (\x -> x ++ ['\n']) (s xs)
lines = \xs -> u (Stream.lines (s xs))
-}
{-
words = Stream.words
unwords = Stream.unwords
-- ** \"Set\" operations
nub = Stream.nub
delete = Stream.delete
(\\) = (Stream.\\)
union = Stream.union
intersect = Stream.intersect
-- ** Ordered lists
sort = Stream.sort
insert = Stream.insert
-- * Generalized functions
-- ** The \"By\" operations
-- *** User-supplied equality (replacing an Eq context)
nubBy = Stream.nubBy
deleteBy = Stream.deleteBy
deleteFirstsBy = Stream.deleteFirstsBy
unionBy = Stream.unionBy
intersectBy = Stream.intersectBy
groupBy = Stream.groupBy
-}
-- *** User-supplied comparison (replacing an Ord context)
{-
sortBy = Stream.sortBy
-}
insertBy = \cmp x xs -> u $ Stream.insertBy cmp x (s xs)
maximumBy = \cmp xs -> Stream.maximumBy cmp (s xs)
minimumBy = \cmp xs -> Stream.minimumBy cmp (s xs)
-- * The \"generic\" operations
genericLength = \xs -> Stream.genericLength (s xs)
genericTake = \n xs -> u $ Stream.genericTake n (s xs)
genericDrop = \n xs -> u $ Stream.genericDrop n (s xs)
genericIndex = \xs n -> Stream.genericIndex (s xs) n
genericSplitAt = \n xs -> Stream.genericSplitAt n (s xs)
genericReplicate = \n x -> genericTake n (Prelude.repeat x)