packages feed

streams 3.0.0.1 → 3.0.1

raw patch · 15 files changed

+1901/−1911 lines, 15 filesdep ~basedep ~comonaddep ~distributive

Dependency ranges changed: base, comonad, distributive, semigroupoids, semigroups

Files

.travis.yml view
@@ -1,1 +1,8 @@ language: haskell+notifications:+  irc:+    channels:+      - "irc.freenode.org#haskell-lens"+    skip_join: true+    template:+      - "\x0313streams\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} %{message}"
− Data/Stream/Future.hs
@@ -1,148 +0,0 @@-{-# LANGUAGE BangPatterns #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Stream.Future--- Copyright   :  (C) 2011 Edward Kmett--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable----------------------------------------------------------------------------------module Data.Stream.Future-  ( Future(..)-  , cons, (<|)-  , head-  , tail-  , length-  , tails-  , map-  , index-  ) where--import Prelude hiding (head, tail, map, length)-import Control.Applicative-import Control.Comonad-import Data.Foldable-import Data.Functor.Alt-import Data.Functor.Extend-import Data.Traversable-import Data.Semigroup hiding (Last)-import Data.Semigroup.Foldable-import Data.Semigroup.Traversable-#ifdef LANGUAGE_DeriveDataTypeable-import Data.Data-#endif--infixr 5 :<, <|--data Future a = Last a | a :< Future a deriving-  ( Eq, Ord, Show, Read-#ifdef LANGUAGE_DeriveDataTypeable-  , Data, Typeable-#endif-  )--(<|) :: a -> Future a -> Future a-(<|) = (:<)-{-# INLINE (<|) #-}--cons :: a -> Future a -> Future a-cons = (:<)-{-# INLINE cons #-}--head :: Future a -> a-head (Last a) = a-head (a :< _) = a-{-# INLINE head #-}--length :: Future a -> Int-length = go 1-  where-    go !n (Last _)  = n-    go !n (_ :< as) = go (n + 1) as-{-# INLINE length #-}--tail :: Future a -> Maybe (Future a)-tail (Last _) = Nothing-tail (_ :< as) = Just as-{-# INLINE tail #-}--tails :: Future a -> Future (Future a)-tails w@(_ :< as) = w :< tails as-tails w@(Last _)  = Last w-{-# INLINE tails #-}--map :: (a -> b) -> Future a -> Future b-map f (a :< as) = f a :< map f as-map f (Last a)  = Last (f a)-{-# INLINE map #-}--index :: Int -> Future a -> a-index n aas-  | n < 0 = error "index: negative index"-  | n == 0 = extract aas-  | otherwise = case aas of-    Last _ -> error "index: out of range"-    _ :< as -> index (n - 1) as--instance Functor Future where-  fmap = map-  b <$ (_ :< as) = b :< (b <$ as)-  b <$ _         = Last b--instance Foldable Future where-  foldMap = foldMapDefault--instance Traversable Future where-  traverse f (Last a)  = Last <$> f a-  traverse f (a :< as) = (:<) <$> f a <*> traverse f as--instance Foldable1 Future--instance Traversable1 Future where-  traverse1 f (Last a)  = Last <$> f a-  traverse1 f (a :< as) = (:<) <$> f a <.> traverse1 f as--instance Extend Future where-  extended = extend--instance Comonad Future where-  extract = head-  duplicate = tails-  extend f w@(_ :< as) = f w :< extend f as-  extend f w@(Last _)  = Last (f w)--instance Apply Future where-  Last f    <.> Last a    = Last (f a)-  (f :< _)  <.> Last a    = Last (f a)-  Last f    <.> (a :< _ ) = Last (f a)-  (f :< fs) <.> (a :< as) = f a :< (fs <.> as)--  Last a    <. _         = Last a-  (a :< _ ) <. Last _    = Last a-  (a :< as) <. (_ :< bs) = a :< (as <. bs)--  _          .> Last b   = Last b-  Last _     .> (b :< _) = Last b-  (_ :< as)  .> (b :< bs) = b :< (as .> bs)--instance ComonadApply Future where-  (<@>) = (<.>)--instance Alt Future where-  Last a    <!> bs = a :< bs-  (a :< as) <!> bs = a :< (as <!> bs)--instance Semigroup (Future a) where-  (<>) = (<!>)--instance Applicative Future where-  pure = Last-  (<*>) = (<.>)-  (<* ) = (<. )-  ( *>) = ( .>)--
− Data/Stream/Future/Skew.hs
@@ -1,426 +0,0 @@-{-# LANGUAGE PatternGuards, BangPatterns #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Stream.Future.Skew--- Copyright   :  (C) 2008-2011 Edward Kmett,---                (C) 2004 Dave Menendez--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable------ Anticausal streams implemented as non-empty skew binary random access lists------ The Applicative zips streams, but since these are potentially infinite--- this is stricter than would be desired. You almost always want----------------------------------------------------------------------------------module Data.Stream.Future.Skew-    ( Future(..)-    , (<|)      -- O(1)-    , cons-    , length    -- O(log n)-    , head      -- O(1)-    , tail      -- O(1)-    , tails-    , last      -- O(log n)-    , uncons    -- O(1)-    , index     -- O(log n)-    , drop      -- O(log n)-    , dropWhile -- O(n)-    , indexed-    , from-    , break-    , span-    , split     -- O(log n)-    , splitW    -- O(log n)-    , repeat-    , replicate -- O(log n)-    , insert    -- O(n)-    , insertBy-    , update-    , adjust    -- O(log n)-    , fromList-    , toFuture-    ) where--import Control.Applicative hiding (empty)-import Control.Comonad-import Data.Functor.Alt-import Data.Functor.Extend-import Data.Foldable hiding (toList)-import Data.Traversable (Traversable, traverse)-import Data.Semigroup hiding (Last)-import Data.Semigroup.Foldable-import Data.Semigroup.Traversable-import Prelude hiding (null, head, tail, drop, dropWhile, length, foldr, last, span, repeat, replicate, break)--infixr 5 :<, <|--data Complete a-    = Tip a-    | Bin {-# UNPACK #-} !Int a !(Complete a) !(Complete a)-    deriving Show--instance Functor Complete where-  fmap f (Tip a) = Tip (f a)-  fmap f (Bin w a l r) = Bin w (f a) (fmap f l) (fmap f r)--instance Extend Complete where-  extended = extend--instance Comonad Complete where-  extend f w@Tip {} = Tip (f w)-  extend f w@(Bin n _ l r) = Bin n (f w) (extend f l) (extend f r)-  extract (Tip a) = a-  extract (Bin _ a _ _) = a--instance Foldable Complete where-  foldMap f (Tip a) = f a-  foldMap f (Bin _ a l r) = f a `mappend` foldMap f l `mappend` foldMap f r-  foldr f z (Tip a) = f a z-  foldr f z (Bin _ a l r) = f a (foldr f (foldr f z r) l)--instance Foldable1 Complete where-  foldMap1 f (Tip a) = f a-  foldMap1 f (Bin _ a l r) = f a <> foldMap1 f l <> foldMap1 f r--instance Traversable Complete where-  traverse f (Tip a) = Tip <$> f a-  traverse f (Bin n a l r) = Bin n <$> f a <*> traverse f l <*> traverse f r--instance Traversable1 Complete where-  traverse1 f (Tip a) = Tip <$> f a-  traverse1 f (Bin n a l r) = Bin n <$> f a <.> traverse1 f l <.> traverse1 f r--bin :: a -> Complete a -> Complete a -> Complete a-bin a l r = Bin (1 + weight l + weight r) a l r-{-# INLINE bin #-}--weight :: Complete a -> Int-weight Tip{} = 1-weight (Bin w _ _ _) = w-{-# INLINE weight #-}---- A future is a non-empty skew binary random access list of nodes.--- The last node, however, is allowed to contain fewer values.-data Future a-  = Last !(Complete a)-  | !(Complete a) :< Future a---  deriving Show---instance Show a => Show (Future a) where-  showsPrec d as = showParen (d >= 10) $-    showString "fromList " . showsPrec 11 (toList as)--instance Functor Future where-  fmap f (t :< ts) = fmap f t :< fmap f ts-  fmap f (Last t) = Last (fmap f t)--instance Extend Future where-  extended = extend--instance Comonad Future where-  extend g (Last t)  = Last (extendTree g t Last)-  extend g (t :< ts) = extendTree g t (:< ts) :< extend g ts-  extract = head--extendTree :: (Future a -> b) -> Complete a -> (Complete a -> Future a) -> Complete b-extendTree g w@Tip{}         f = Tip (g (f w))-extendTree g w@(Bin n _ l r) f = Bin n (g (f w)) (extendTree g l (:< f r))  (extendTree g r f)--instance Apply Future where-  Last (Tip f)         <.> as                   = singleton (f (extract as))-  fs                   <.> Last (Tip a)         = singleton (extract fs a)-  Last (Bin _ f lf rf) <.> Last (Bin _ a la ra) = f a <| (lf :< Last rf  <.> la :< Last ra )-  Last (Bin _ f lf rf) <.> Bin _ a la ra :< as  = f a <| (lf :< Last rf  <.> la :< ra :< as)-  Last (Bin _ f lf rf) <.> Tip a :< as          = f a <| (lf :< Last rf  <.> as            )-  Bin _ f lf rf :< fs  <.> Last (Bin _ a la ra) = f a <| (lf :< rf :< fs <.> la :< Last ra )-  Bin _ f lf rf :< fs  <.> Tip a :< as          = f a <| (lf :< rf :< fs <.> as            )-  Bin _ f lf rf :< fs  <.> Bin _ a la ra :< as  = f a <| (lf :< rf :< fs <.> la :< ra :< as)-  Tip f :< fs          <.> Tip a :< as          = f a <| (fs             <.> as            )-  Tip f :< fs          <.> Bin _ a la ra :< as  = f a <| (fs             <.> la :< ra :< as)-  Tip f :< fs          <.> Last (Bin _ a la ra) = f a <| (fs             <.> la :< Last ra )--instance ComonadApply Future where-  (<@>) = (<.>)--instance Applicative Future where-  pure = repeat-  (<*>) = (<.>)--instance Alt Future where-  as <!> bs = foldr (<|) bs as--instance Foldable Future where-  foldMap f (t :< ts) = foldMap f t `mappend` foldMap f ts-  foldMap f (Last t) = foldMap f t-  foldr f z (t :< ts) = foldr f (foldr f z ts) t-  foldr f z (Last t) = foldr f z t--toList :: Future a -> [a]-toList = foldr (:) []--instance Foldable1 Future where-  foldMap1 f (t :< ts) = foldMap1 f t <> foldMap1 f ts-  foldMap1 f (Last t) = foldMap1 f t--instance Traversable Future where-  traverse f (t :< ts) = (:<) <$> traverse f t <*> traverse f ts-  traverse f (Last t) = Last <$> traverse f t--instance Traversable1 Future where-  traverse1 f (t :< ts) = (:<) <$> traverse1 f t <.> traverse1 f ts-  traverse1 f (Last t) = Last <$> traverse1 f t--repeat :: a -> Future a-repeat a0 = go a0 (Tip a0)-    where-      go :: a -> Complete a -> Future a-      go a as | ass <- bin a as as = as :< go a ass-{-# INLINE repeat #-}---- | /O(log n)/-replicate :: Int -> a -> Future a-replicate n a-  | n <= 0    = error "replicate: non-positive argument"-  | otherwise = go 1 n a (Tip a) (\ _ r -> r)-  where-  -- invariants:-  -- tb is a complete tree of i nodes all equal to b-  -- 1 <= i = 2^m-1 <= j-  -- k accepts r such that 0 <= r < i-  go :: Int -> Int -> b -> Complete b -> (Int -> Future b -> r) -> r-  go !i !j b tb k-    | j >= i2p1 = go i2p1 j b (Bin i2p1 b tb tb) k'-    | j >= i2   = k (j - i2) (tb :< Last tb)-    | otherwise = k (j - i) (Last tb)-    where-      i2 = i * 2-      i2p1 = i2 + 1-      k' r xs-        | r >= i2   = k (r - i2) (tb :< tb :< xs)-        | r >= i    = k (r - i) (tb :< xs)-        | otherwise = k r xs-{-# INLINE replicate #-}--mapWithIndex :: (Int -> a -> b) -> Future a -> Future b-mapWithIndex f0 as0 = spine f0 0 as0-  where-    spine f m (Last as) = Last (tree f m as)-    spine f m (a :< as) = tree f m a :< spine f (m + weight a) as-    tree f m (Tip a) = Tip (f m a)-    tree f m (Bin n a l r) = Bin n (f m a) (tree f (m + 1) l) (tree f (m + 1 + weight l) r)--indexed :: Future a -> Future (Int, a)-indexed = mapWithIndex (,)-{-# INLINE indexed #-}--from :: Num a => a -> Future a-from a = mapWithIndex ((+) . fromIntegral) (pure a)-{-# INLINE from #-}---- | /O(1)/-singleton :: a -> Future a-singleton a = Last (Tip a)-{-# INLINE singleton #-}---- | /O(log n)/.-length :: Future a -> Int-length (Last t) = weight t-length (t :< ts) = weight t + length ts---- | /O(1)/ cons-(<|) :: a -> Future a -> Future a-a <| (l :< Last r)-  | weight l == weight r = Last (bin a l r)-a <| (l :< r :< as)-  | weight l == weight r = bin a l r :< as-a <| as = Tip a :< as-{-# INLINE (<|) #-}---cons :: a -> Future a -> Future a-cons = (<|)-{-# INLINE cons #-}---- | /O(1)/-head :: Future a -> a-head (a :< _) = extract a-head (Last a) = extract a-{-# INLINE head #-}---- | /O(1)/.-tail :: Future a -> Maybe (Future a)-tail (Tip{} :< ts) = Just ts-tail (Bin _ _ l r :< ts) = Just (l :< r :< ts)-tail (Last Tip{}) = Nothing-tail (Last (Bin _ _ l r)) = Just (l :< Last r)-{-# INLINE tail #-}--tails :: Future a -> Future (Future a)-tails = duplicate-{-# INLINE tails #-}---- | /O(log n)/.-last :: Future a -> a-last (_ :< as) = last as-last (Last as) = go as-  where go (Tip a) = a-        go (Bin _ _ _ r) = go r---- | /O(1)/.-uncons :: Future a -> (a, Maybe (Future a))-uncons (Last (Tip a))       = (a, Nothing)-uncons (Last (Bin _ a l r)) = (a, Just (l :< Last r))-uncons (Tip a       :< as)  = (a, Just as)-uncons (Bin _ a l r :< as)  = (a, Just (l :< r :< as))-{-# INLINE uncons #-}---- | /O(log n)/.-index :: Int -> Future a -> a-index i (Last t)-  | i < weight t = indexComplete i t-  | otherwise    = error "index: out of range"-index i (t :< ts)-  | i < w     = indexComplete i t-  | otherwise = index (i - w) ts-  where w = weight t--indexComplete :: Int -> Complete a -> a-indexComplete 0 (Tip a) = a-indexComplete i (Bin w a l r)-  | i == 0    = a-  | i <= w'   = indexComplete (i-1) l-  | otherwise = indexComplete (i-1-w') r-  where w' = div w 2-indexComplete _ _ = error "index: index out of range"---- | /O(log n)/.-drop :: Int -> Future a -> Maybe (Future a)-drop 0 ts = Just ts-drop i (t :< ts) = case compare i w of-  LT -> Just (dropComplete i t (:< ts))-  EQ -> Just ts-  GT -> drop (i - w) ts-  where w = weight t-drop i (Last t)-  | i < w     = Just (dropComplete i t Last)-  | otherwise = Nothing-  where w = weight t--dropComplete :: Int -> Complete a -> (Complete a -> Future a) -> Future a-dropComplete 0 t f             = f t-dropComplete 1 (Bin _ _ l r) f = l :< f r-dropComplete i (Bin w _ l r) f = case compare (i - 1) w' of-  LT -> dropComplete (i-1) l (:< f r)-  EQ -> f r-  GT -> dropComplete (i-1-w') r f-  where w' = div w 2-dropComplete _ _ _ = error "drop: index out of range"---- /O(n)/.-dropWhile :: (a -> Bool) -> Future a -> Maybe (Future a)-dropWhile p as-  | p (head as) = tail as >>= dropWhile p-  | otherwise = Just as---- /O(n)/-span :: (a -> Bool) -> Future a -> ([a], Maybe (Future a))-span p aas = case uncons aas of-  (a, Just as) | p a, (ts, fs) <- span p as -> (a:ts, fs)-  (a, Nothing) | p a                        -> ([a], Nothing)-  (_, _)                                    -> ([], Just aas)---- /O(n)/-break :: (a -> Bool) -> Future a -> ([a], Maybe (Future a))-break p = span (not . p)---- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.--- best used with a monotonic function-split :: (a -> Bool) -> Future a -> ([a], Maybe (Future a))-split p l@(Last a)-  | p (extract a)  = ([], Just l)-  | otherwise      = splitComplete p a Last-split p (a :< as)-  | p (extract as) = splitComplete p a (:< as)-  | (ts, fs) <- split p as = (foldr (:) ts a, fs)---- for use when we know the split occurs within a given tree-splitComplete :: (a -> Bool) -> Complete a -> (Complete a -> Future a) -> ([a], Maybe (Future a))-splitComplete p t@(Tip a) f-  | p a       = ([], Just (f t))-  | otherwise = ([a], Nothing)-splitComplete p t@(Bin _ a l r) f-  | p a                                               = ([], Just (f t))-  | p (extract r), (ts, fs) <- splitComplete p l (:< f r) = (a:ts, fs)-  |                (ts, fs) <- splitComplete p r f        = (a:foldr (:) ts l, fs)---- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.--- best used with a monotonic function------ > splitW p xs = (map extract &&& fmap (fmap extract)) . split p . duplicate-splitW :: (Future a -> Bool) -> Future a -> ([a], Maybe (Future a))-splitW p l@(Last a)-  | p l       = ([], Just l)-  | otherwise = splitCompleteW p a Last-splitW p (a :< as)-  | p as                    = splitCompleteW p a (:< as)-  | (ts, fs) <- splitW p as = (foldr (:) ts a, fs)---- for use when we know the split occurs within a given tree-splitCompleteW :: (Future a -> Bool) -> Complete a -> (Complete a -> Future a) -> ([a], Maybe (Future a))-splitCompleteW p t@(Tip a) f-  | w <- f t, p w = ([], Just w)-  | otherwise = ([a], Nothing)-splitCompleteW p t@(Bin _ a l r) f-  | w <- f t, p w                                    = ([], Just w)-  | w <- f r, p w, (ts, fs) <- splitCompleteW p l (:< w) = (a:ts, fs)-  |                (ts, fs) <- splitCompleteW p r f      = (a:foldr (:) ts l, fs)--fromList :: [a] -> Future a-fromList [] = error "fromList: empty list"-fromList (x:xs) = go x xs-  where go a [] = singleton a-        go a (b:bs) = a <| go b bs--toFuture :: [a] -> Maybe (Future a)-toFuture [] = Nothing-toFuture xs = Just (fromList xs)---- /O(n)/-insert :: Ord a => a -> Future a -> Future a-insert a as = case split (a<=) as of-    (_, Nothing)  -> foldr (<|) (singleton a) as-    (ts, Just as') -> foldr (<|) (a <| as') ts---- /O(n)/. Finds the split in O(log n), but then has to recons-insertBy :: (a -> a -> Ordering) -> a -> Future a -> Future a-insertBy cmp a as = case split (\b -> cmp a b <= EQ) as of-    (_, Nothing)  -> foldr (<|) (singleton a) as-    (ts, Just as') -> foldr (<|) (a <| as') ts---- /O(log n)/ Change the value of the nth entry in the future-adjust :: Int -> (a -> a) -> Future a -> Future a-adjust !n f d@(Last a)-  | n < weight a = Last (adjustComplete n f a)-  | otherwise = d-adjust !n f (a :< as)-  | n < w = adjustComplete n f a :< as-  | otherwise = a :< adjust (n - w) f as-  where w = weight a--adjustComplete :: Int -> (a -> a) -> Complete a -> Complete a-adjustComplete 0 f (Tip a) = Tip (f a)-adjustComplete _ _ t@Tip{} = t-adjustComplete n f (Bin m a l r)-  | n == 0 = Bin m (f a) l r-  | n < w = Bin m a (adjustComplete (n - 1) f l) r-  | otherwise = Bin m a l (adjustComplete (n - 1 - w) f r)-  where w = weight l--update :: Int -> a -> Future a -> Future a-update n = adjust n . const
− Data/Stream/Infinite.hs
@@ -1,455 +0,0 @@-{-# LANGUAGE PatternGuards #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Stream.Infinite--- Copyright   :  (C) 2011 Edward Kmett,---                (C) 2007-2010 Wouter Swierstra, Bas van Dijk--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable (Haskell 2010)---------------------------------------------------------------------------------module Data.Stream.Infinite (-   -- * The type of streams-     Stream(..)-   -- * Basic functions-   , head   -- :: Stream a -> a-   , tail   -- :: Stream a -> Stream a-   , inits  -- :: Stream a -> Stream [a]-   , tails  -- :: Stream a -> Stream (Stream a)-   -- * Stream transformations-   , map         -- :: (a -> b) -> Stream a -> Stream b-   , intersperse -- :: a -> Stream a -> Stream-   , interleave  -- :: Stream a -> Stream a -> Stream a-   , scanl       -- :: (b -> a -> b) -> b -> Stream a -> Stream b-   , scanl'      -- :: (b -> a -> b) -> b -> Stream a -> Stream b-   , scanl1      -- :: (a -> a -> a) -> Stream a -> Stream a-   , scanl1'     -- :: (a -> a -> a) -> Stream a -> Stream a-   , transpose   -- :: Stream (Stream a) -> Stream (Stream a)-   -- * Building streams-   , iterate     -- :: (a -> a) -> a -> Stream a-   , repeat      -- :: a -> Stream a-   , cycle       -- :: NonEmpty a -> Stream a-   , unfold      -- :: (a -> (b, a)) -> a -> Stream b-   -- * Extracting sublists-   , take        -- :: Int -> Stream a -> [a]-   , drop        -- :: Int -> Stream a -> Stream a-   , splitAt     -- :: Int -> Stream a -> ([a],Stream a)-   , takeWhile   -- :: (a -> Bool) -> Stream a -> [a]-   , dropWhile   -- :: (a -> Bool) -> Stream a -> Stream a-   , span        -- :: (a -> Bool) -> Stream a -> ([a], Stream a)-   , break       -- :: (a -> Bool) -> Stream a -> ([a], Stream a)-   , filter      -- :: (a -> Bool) -> Stream a -> Stream a-   , partition   -- :: (a -> Bool) -> Stream a -> (Stream a, Stream a)-   , group       -- :: (a -> Bool) -> Stream a -> Stream (NonEmpty a)-   , groupBy     -- :: (a -> a -> Bool) -> Stream a -> Stream (NonEmpty a)-   -- * Sublist predicates-   , isPrefixOf  -- :: [a] -> Stream a -> Bool-   -- * Indexing streams -   , (!!)        -- :: Int -> Stream a -> a-   , elemIndex   -- :: Eq a => a -> Stream a -> Int-   , elemIndices -- :: Eq a => a -> Stream a -> Stream Int-   , findIndex   -- :: (a -> Bool) -> Stream a -> Int-   , findIndices -- :: (a -> Bool) -> Stream a -> Stream Int-   -- * Zipping and unzipping streams-   , zip         -- :: Stream a -> Stream b -> Stream (a, b)-   , zipWith     -- :: (a -> b -> c) -> Stream a -> Stream b -> Stream c-   , unzip       -- :: Functor f => f (a, b) -> (f a, f b)-   -- * Functions on streams of characters-   , words       -- :: Stream Char -> Stream String-   , unwords     -- :: Stream String -> Stream Char-   , lines       -- :: Stream Char -> Stream String-   , unlines     -- :: Stream String -> Stream Char-   -- * Converting to and from an infinite list-   , fromList    -- :: [a] -> Stream a-   ) where--import Prelude hiding -  ( head, tail, map, scanr, scanr1, scanl, scanl1-  , iterate, take, drop, takeWhile-  , dropWhile, repeat, cycle, filter-  , (!!), zip, unzip, zipWith, words-  , unwords, lines, unlines, break, span-  , splitAt, foldr-  )--import Control.Applicative-import Control.Comonad-import Data.Char (isSpace)-import Data.Data-import Data.Functor.Apply-import Data.Functor.Extend-import Data.Semigroup-import Data.Foldable-import Data.Traversable-import Data.Distributive-import Data.Semigroup.Traversable-import Data.Semigroup.Foldable-import Data.List.NonEmpty (NonEmpty(..))--data Stream a = a :> Stream a deriving -  ( Show-#ifdef LANGUAGE_DeriveDataTypeable-  , Data, Typeable-#endif-  )--infixr 5 :>---- | Map a pure function over a stream-map :: (a -> b) -> Stream a -> Stream b-map f (a :> as) = f a :> map f as--instance Functor Stream where-  fmap = map-  b <$ _ = repeat b--instance Distributive Stream where-  distribute w = fmap head w :> distribute (fmap tail w)---- | Extract the first element of the sequence.-head :: Stream a -> a-head (a :> _) = a-{-# INLINE head #-}---- | Extract the sequence following the head of the stream.-tail :: Stream a -> Stream a-tail (_ :> as) = as-{-# INLINE tail #-}---- | The 'tails' function takes a stream @xs@ and returns all the--- suffixes of @xs@.-tails :: Stream a -> Stream (Stream a)-tails w = w :> tails (tail w)--instance Extend Stream where-  duplicated = tails-  extended f w = f w :> extended f (tail w)--instance Comonad Stream where-  duplicate = tails-  extend f w = f w :> extend f (tail w)-  extract = head--instance Apply Stream where-  (f :> fs) <.> (a :> as) = f a :> (fs <.> as)-  as        <.  _         = as-  _          .> bs        = bs--instance ComonadApply Stream where-  (f :> fs) <@> (a :> as) = f a :> (fs <@> as)-  as        <@  _         = as-  _          @> bs        = bs---- | 'repeat' @x@ returns a constant stream, where all elements are--- equal to @x@.-repeat :: a -> Stream a-repeat a = as where as = a :> as--instance Applicative Stream where-  pure = repeat-  (<*>) = (<.>)-  (<* ) = (<. )-  ( *>) = ( .>)--instance Foldable Stream where-  fold (m :> ms) = m `mappend` fold ms-  foldMap f (a :> as) = f a `mappend` foldMap f as-  foldr f0 _ = go f0 where go f (a :> as) = f a (go f as)--instance Traversable Stream where-  traverse f ~(a :> as) = (:>) <$> f a <*> traverse f as--instance Foldable1 Stream--instance Traversable1 Stream where-  traverse1 f ~(a :> as) = (:>) <$> f a <.> traverse1 f as-  sequence1 ~(a :> as) = (:>) <$> a <.> sequence1 as---- | The unfold function is similar to the unfold for lists. Note--- there is no base case: all streams must be infinite.-unfold :: (a -> (b, a)) -> a -> Stream b-unfold f c | (x, d) <- f c = x :> unfold f d--instance Monad Stream where-  return = repeat-  m >>= f = unfold (\(bs :> bss) -> (head bs, tail <$> bss)) (fmap f m)-  _ >> bs = bs---- | Interleave two Streams @xs@ and @ys@, alternating elements--- from each list.------ > [x1,x2,...] `interleave` [y1,y2,...] == [x1,y1,x2,y2,...]-interleave :: Stream a -> Stream a -> Stream a-interleave ~(x :> xs) ys = x :> interleave ys xs--instance Semigroup (Stream a) where-  (<>) = interleave---- | The 'inits' function takes a stream @xs@ and returns all the--- finite prefixes of @xs@.------ Note that this 'inits' is lazier then @Data.List.inits@:------ > inits _|_ = [] ::: _|_------ while for @Data.List.inits@:------ > inits _|_ = _|_-inits :: Stream a -> Stream [a]-inits xs = [] :> ((head xs :) <$> inits (tail xs))---- | @'intersperse' y xs@ creates an alternating stream of--- elements from @xs@ and @y@.-intersperse :: a -> Stream a -> Stream a-intersperse y ~(x :> xs) = x :> y :> intersperse y xs---- | 'scanl' yields a stream of successive reduced values from:------ > scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]-scanl :: (a -> b -> a) -> a -> Stream b -> Stream a-scanl f z ~(x :> xs) = z :> scanl f (f z x) xs---- | 'scanl' yields a stream of successive reduced values from:------ > scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]-scanl' :: (a -> b -> a) -> a -> Stream b -> Stream a-scanl' f z ~(x :> xs) = z :> (scanl' f $! f z x) xs---- | 'scanl1' is a variant of 'scanl' that has no starting value argument:------ > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...]-scanl1 :: (a -> a -> a) -> Stream a -> Stream a-scanl1 f ~(x :> xs) = scanl f x xs---- | @scanl1'@ is a strict 'scanl' that has no starting value.-scanl1' :: (a -> a -> a) -> Stream a -> Stream a-scanl1' f ~(x :> xs) = scanl' f x xs---- | 'transpose' computes the transposition of a stream of streams.-transpose :: Stream (Stream a) -> Stream (Stream a)-transpose ~((x :> xs) :> yss) =-  (x :> (head <$> yss)) :> transpose (xs :> (tail <$> yss))---- | @'iterate' f x@ produces the infinite sequence--- of repeated applications of @f@ to @x@.------ > iterate f x = [x, f x, f (f x), ..]-iterate :: (a -> a) -> a -> Stream a-iterate f x = x :> iterate f (f x)---- | @'cycle' xs@ returns the infinite repetition of @xs@:------ > cycle [1,2,3] = Cons 1 (Cons 2 (Cons 3 (Cons 1 (Cons 2 ...-cycle :: NonEmpty a -> Stream a-cycle xs = ys where ys = foldr (:>) ys xs---- | @'take' n xs@ returns the first @n@ elements of @xs@.------ /Beware/: passing a negative integer as the first argument will--- cause an error.-take :: Int -> Stream a -> [a]-take n ~(x :> xs)-  | n == 0 = []-  | n > 0 = x : take (n - 1) xs-  | otherwise = error "Stream.take: negative argument"---- | @'drop' n xs@ drops the first @n@ elements off the front of--- the sequence @xs@.------ /Beware/: passing a negative integer as the first argument will--- cause an error.-drop :: Int -> Stream a -> Stream a-drop n xs-  | n == 0 = xs-  | n > 0 = drop (n - 1) (tail xs)-  | otherwise = error "Stream.drop: negative argument"---- | @'splitAt' n xs@ returns a pair consisting of the prefix of --- @xs@ of length @n@ and the remaining stream immediately following --- this prefix.------ /Beware/: passing a negative integer as the first argument will--- cause an error.-splitAt :: Int -> Stream a -> ([a],Stream a)-splitAt n xs-  | n == 0 = ([],xs)-  | n > 0, (prefix, rest) <- splitAt (n - 1) (tail xs) = (head xs : prefix, rest)-  | otherwise = error "Stream.splitAt: negative argument"---- | @'takeWhile' p xs@ returns the longest prefix of the stream--- @xs@ for which the predicate @p@ holds.-takeWhile :: (a -> Bool) -> Stream a -> [a]-takeWhile p (x :> xs) -  | p x = x : takeWhile p xs-  | otherwise = []---- | @'dropWhile' p xs@ returns the suffix remaining after--- @'takeWhile' p xs@.------ /Beware/: this function may diverge if every element of @xs@--- satisfies @p@, e.g.  @dropWhile even (repeat 0)@ will loop.-dropWhile :: (a -> Bool) -> Stream a -> Stream a-dropWhile p ~(x :> xs)-  | p x = dropWhile p xs-  | otherwise = x :> xs---- | @'span' p xs@ returns the longest prefix of @xs@ that satisfies--- @p@, together with the remainder of the stream.-span :: (a -> Bool) -> Stream a -> ([a], Stream a)-span p xxs@(x :> xs)-  | p x, (ts, fs) <- span p xs = (x : ts, fs)-  | otherwise = ([], xxs)---- | The 'break' @p@ function is equivalent to 'span' @not . p@.-break :: (a -> Bool) -> Stream a -> ([a], Stream a)-break p = span (not . p)---- | @'filter' p xs@, removes any elements from @xs@ that do not satisfy @p@.------ /Beware/: this function may diverge if there is no element of--- @xs@ that satisfies @p@, e.g.  @filter odd (repeat 0)@ will loop.-filter :: (a -> Bool) -> Stream a -> Stream a-filter p ~(x :> xs) -  | p x       = x :> filter p xs-  | otherwise = filter p xs---- | The 'partition' function takes a predicate @p@ and a stream--- @xs@, and returns a pair of streams. The first stream corresponds--- to the elements of @xs@ for which @p@ holds; the second stream--- corresponds to the elements of @xs@ for which @p@ does not hold.------ /Beware/: One of the elements of the tuple may be undefined. For--- example, @fst (partition even (repeat 0)) == repeat 0@; on the--- other hand @snd (partition even (repeat 0))@ is undefined.-partition :: (a -> Bool) -> Stream a -> (Stream a, Stream a)-partition p ~(x :> xs)-  | p x = (x :> ts, fs)-  | otherwise = (ts, x :> fs)-  where (ts, fs) = partition p xs---- | The 'group' function takes a stream and returns a stream of--- lists such that flattening the resulting stream is equal to the--- argument.  Moreover, each sublist in the resulting stream--- contains only equal elements.  For example,------ > group $ cycle "Mississippi" = "M" ::: "i" ::: "ss" ::: "i" ::: "ss" ::: "i" ::: "pp" ::: "i" ::: "M" ::: "i" ::: ...-group :: Eq a => Stream a -> Stream (NonEmpty a)-group = groupBy (==)--groupBy :: (a -> a -> Bool) -> Stream a -> Stream (NonEmpty a)-groupBy eq ~(x :> ys) -  | (xs, zs) <- span (eq x) ys -  = (x :| xs) :> groupBy eq zs---- | The 'isPrefix' function returns @True@ if the first argument is--- a prefix of the second.-isPrefixOf :: Eq a => [a] -> Stream a -> Bool-isPrefixOf [] _ = True-isPrefixOf (y:ys) (x :> xs)-  | y == x    = isPrefixOf ys xs-  | otherwise = False---- | @xs !! n@ returns the element of the stream @xs@ at index--- @n@. Note that the head of the stream has index 0.------ /Beware/: passing a negative integer as the first argument will cause--- an error.-(!!) :: Stream a -> Int -> a-(!!) (x :> xs) n-  | n == 0    = x-  | n > 0     = xs !! (n - 1)-  | otherwise = error "Stream.!! negative argument"---- | The 'elemIndex' function returns the index of the first element--- in the given stream which is equal (by '==') to the query element,------ /Beware/: @'elemIndex' x xs@ will diverge if none of the elements--- of @xs@ equal @x@.-elemIndex :: Eq a => a -> Stream a -> Int-elemIndex x = findIndex (\y -> x == y)---- | The 'elemIndices' function extends 'elemIndex', by returning the--- indices of all elements equal to the query element, in ascending order.------ /Beware/: 'elemIndices' @x@ @xs@ will diverge if any suffix of--- @xs@ does not contain @x@.-elemIndices :: Eq a => a -> Stream a -> Stream Int-elemIndices x = findIndices (x==)---- | The 'findIndex' function takes a predicate and a stream and returns--- the index of the first element in the stream that satisfies the predicate,------ /Beware/: 'findIndex' @p@ @xs@ will diverge if none of the elements of--- @xs@ satisfy @p@.-findIndex :: (a -> Bool) -> Stream a -> Int-findIndex p = indexFrom 0-    where-    indexFrom ix (x :> xs) -      | p x       = ix-      | otherwise = (indexFrom $! (ix + 1)) xs---- | The 'findIndices' function extends 'findIndex', by returning the--- indices of all elements satisfying the predicate, in ascending--- order.------ /Beware/: 'findIndices' @p@ @xs@ will diverge if all the elements--- of any suffix of @xs@ fails to satisfy @p@.-findIndices :: (a -> Bool) -> Stream a -> Stream Int-findIndices p = indicesFrom 0 where-  indicesFrom ix (x :> xs) -    | p x = ix :> ixs -    | otherwise = ixs-    where ixs = (indicesFrom $! (ix+1)) xs---- | The 'zip' function takes two streams and returns a list of--- corresponding pairs.-zip :: Stream a -> Stream b -> Stream (a,b)-zip ~(x :> xs) ~(y :> ys) = (x,y) :> zip xs ys---- | The 'zipWith' function generalizes 'zip'. Rather than tupling--- the functions, the elements are combined using the function--- passed as the first argument to 'zipWith'.-zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c-zipWith f ~(x :> xs) ~(y :> ys) = f x y :> zipWith f xs ys---- | The 'unzip' function is the inverse of the 'zip' function.-unzip :: Stream (a,b) -> (Stream a, Stream b)-unzip xs = (fst <$> xs, snd <$> xs)---- | The 'words' function breaks a stream of characters into a--- stream of words, which were delimited by white space.------ /Beware/: if the stream of characters @xs@ does not contain white--- space, accessing the tail of @words xs@ will loop.-words :: Stream Char -> Stream String-words xs | (w, ys) <- break isSpace xs = w :> words ys---- | The 'unwords' function is an inverse operation to 'words'. It--- joins words with separating spaces.-unwords :: Stream String -> Stream Char-unwords ~(x :> xs) = foldr (:>) (' ' :> unwords xs) x---- | The 'lines' function breaks a stream of characters into a list--- of strings at newline characters. The resulting strings do not--- contain newlines.------ /Beware/: if the stream of characters @xs@ does not contain--- newline characters, accessing the tail of @lines xs@ will loop.-lines :: Stream Char -> Stream String-lines xs | (l, ys) <- break (== '\n') xs = l :> lines (tail ys)---- | The 'unlines' function is an inverse operation to 'lines'. It--- joins lines, after appending a terminating newline to each.-unlines :: Stream String -> Stream Char-unlines ~(x :> xs) = foldr (:>) ('\n' :> unlines xs) x---- | The 'fromList' converts an infinite list to a--- stream.------ /Beware/: Passing a finite list, will cause an error.-fromList :: [a] -> Stream a-fromList (x:xs) = x :> fromList xs-fromList []     = error "Stream.listToStream applied to finite list"
− Data/Stream/Infinite/Functional/Zipper.hs
@@ -1,334 +0,0 @@-{-# LANGUAGE CPP, PatternGuards, BangPatterns #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Zipper.Infinite.Functional.Zipper--- Copyright   :  (C) 2011 Edward Kmett,--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable------ This is an infinite bidirectional zipper------------------------------------------------------------------------------module Data.Stream.Infinite.Functional.Zipper (-   -- * The type of streams-     Zipper(..)-   , tail   -- :: Zipper a -> Zipper a-   , untail -- :: Zipper a -> Zipper a -   , intersperse -- :: a -> Zipper a -> Zipper a-   , interleave  -- :: Zipper a -> Zipper a -> Zipper a-   , transpose   -- :: Zipper (Zipper a) -> Zipper (Zipper a)-   , take        -- :: Integer -> Zipper a -> [a]-   , drop        -- :: Integer -> Zipper a -> Zipper a -- you can drop a negative number-   , splitAt     -- :: Integer -> Zipper a -> ([a],Zipper a)-   , reverse     -- :: Zipper a -> Zipper a-   , (!!)        -- :: Int -> Zipper a -> a-   , unzip       -- :: Functor f => f (a, b) -> (f a, f b)-   , toSequence  -- :: (Integer -> a) -> Zipper a-   , head-   , (<|)-   , uncons-   , takeWhile-   , dropWhile-   , span-   , break-   , isPrefixOf-   , findIndex-   , elemIndex-   , zip-   , zipWith-   ) where--import Prelude hiding -  ( head, tail, map, scanr, scanr1, scanl, scanl1-  , iterate, take, drop, takeWhile-  , dropWhile, repeat, cycle, filter-  , (!!), zip, unzip, zipWith, words-  , unwords, lines, unlines, break, span-  , splitAt, foldr-  )--import Control.Applicative-import Control.Comonad--- import Data.Char (isSpace)-#ifdef LANGUAGE_DeriveDataTypeable-import Data.Data-#endif-import Data.Functor.Extend-import Data.Functor.Apply--- import Data.Monoid-import Data.Semigroup--- import Data.Foldable--- import Data.Traversable--- import Data.Semigroup.Traversable--- import Data.Semigroup.Foldable--- import Data.Zipper.NonEmpty (NonEmpty(..))--data Zipper a = !Integer :~ !(Integer -> a)-#ifdef LANGUAGE_DeriveDataTypeable-  deriving Typeable-#endif--toSequence :: (Integer -> a) -> Zipper a-toSequence = (0 :~) --infixr 0 :~--instance Functor Zipper where-  fmap g (n :~ f) = n :~ g . f-  b <$ _ = 0 :~ const b---- | Extract the focused element-head :: Zipper a -> a-head (n :~ f) = f n---- | Move the head of the zipper to the right-tail :: Zipper a -> Zipper a-tail (n :~ f) = n + 1 :~ f---- | Move the head of the zipper to the left-untail :: Zipper a -> Zipper a-untail (n :~ f) = n - 1 :~ f---- | Cons before the head of the zipper. The head now points to the new element-(<|) :: a -> Zipper a -> Zipper a-a <| (n :~ f) = n :~ \z -> case compare z n of-  LT -> f n-  EQ -> a-  GT -> f (n - 1)---- | Move the head of the zipper one step to the right, returning the value we move over.-uncons :: Zipper a -> (a, Zipper a)-uncons (n :~ f) = (f n, n + 1 :~ f)--instance Extend Zipper where-  duplicated (n :~ f) = n :~ (:~ f)--instance Comonad Zipper where-  duplicate (n :~ f) = n :~ (:~ f)-  extract (n :~ f) = f n--instance Apply Zipper where-  (nf :~ f) <.> (na :~ a) -    | dn <- na - nf-    = nf :~ \n -> f n (a (n + dn))-  as        <.  _         = as-  _          .> bs        = bs--instance ComonadApply Zipper where-  (<@>) = (<.>)-  (<@) = (<.)-  (@>) = (.>)---instance Applicative Zipper where-  pure = repeat-  (<*>) = (<.>)-  as <* _ = as-  _ *> bs = bs--instance Monad Zipper where-  return = repeat-  (z :~ ma) >>= f = z :~ \ na -> case f (ma na) of-    nb :~ mb -> mb (nb + na - z)--repeat :: a -> Zipper a-repeat a = 0 :~ const a---- | Interleave two Zippers @xs@ and @ys@, alternating elements--- from each list.------ > [x1,x2,...] `interleave` [y1,y2,...] == [x1,y1,x2,y2,...]--- > interleave = (<>) -interleave :: Zipper a -> Zipper a -> Zipper a-interleave = (<>) -instance Semigroup (Zipper a) where-  (n :~ a) <> (m :~ b) = 0 :~ \p -> case quotRem p 2 of -    (q, 0) -> a (n + q)-    (q, _) -> b (m + q)---- | @'intersperse' y xs@ creates an alternating stream of--- elements from @xs@ and @y@.-intersperse :: a -> Zipper a -> Zipper a-intersperse y z = z <> repeat y---- | 'transpose' computes the transposition of a stream of streams.-transpose :: Zipper (Zipper a) -> Zipper (Zipper a)-transpose (n :~ f) = 0 :~ \z -> n :~ \n' -> let m :~ g = f n' in g (m + z)--take :: Integer -> Zipper a -> [a]-take n0 (m0 :~ f0)-  | n0 < 0 = error "Zipper.take: negative argument"-  | otherwise = go n0 m0 f0-  where-    go 0 !_ !_ = []-    go n  m  f = f m : go (n - 1) (m + 1) f-  --- | @'drop' n xs@ drops the first @n@ elements off the front of--- the sequence @xs@.-drop :: Integer -> Zipper a -> Zipper a-drop m (n :~ f) = m + n :~ f---- | @'splitAt' n xs@ returns a pair consisting of the prefix of --- @xs@ of length @n@ and the remaining stream immediately following --- this prefix.------ /Beware/: passing a negative integer as the first argument will--- cause an error if you access the taken portion-splitAt :: Integer -> Zipper a -> ([a],Zipper a)-splitAt n xs = (take n xs, drop n xs)---- | @'takeWhile' p xs@ returns the longest prefix of the stream--- @xs@ for which the predicate @p@ holds.-takeWhile :: (a -> Bool) -> Zipper a -> [a]-takeWhile p0 (n0 :~ f0) = go p0 n0 f0 where -  go !p !n !f -    | x <- f n, p x = x : go p (n + 1) f-    | otherwise = []---- | @'dropWhile' p xs@ returns the suffix remaining after--- @'takeWhile' p xs@.------ /Beware/: this function may diverge if every element of @xs@--- satisfies @p@, e.g.  @dropWhile even (repeat 0)@ will loop.-dropWhile :: (a -> Bool) -> Zipper a -> Zipper a-dropWhile p xs@(_ :~ f) = findIndex' p xs :~ f---- | @'span' p xs@ returns the longest prefix of @xs@ that satisfies--- @p@, together with the remainder of the stream.-span :: (a -> Bool) -> Zipper a -> ([a], Zipper a)-span p0 (n0 :~ f0) -  | (ts, n') <- go p0 n0 f0 = (ts, n' :~ f0) where-  go !p !n !f-    | x <- f n, p x, (ts, fs) <- go p (n + 1) f = (x:ts, fs)-    | otherwise = ([], n)---- | The 'break' @p@ function is equivalent to 'span' @not . p@.-break :: (a -> Bool) -> Zipper a -> ([a], Zipper a)-break p = span (not . p)---- | The 'isPrefix' function returns @True@ if the first argument is--- a prefix of the second.-isPrefixOf :: Eq a => [a] -> Zipper a -> Bool-isPrefixOf xs0 (n0 :~ f0) = go xs0 n0 f0 where-  go [] !_ !_ = True-  go (y:ys) n f = y == f n && go ys (n + 1) f---- | @xs !! n@ returns the element of the stream @xs@ at index--- @n@. Note that the head of the stream has index 0.------ /Beware/: passing a negative integer as the first argument will cause--- an error.-(!!) :: Zipper a -> Integer -> a-(!!) (n :~ f) m = f (n + m)---- | The 'findIndex' function takes a predicate and a stream and returns--- the index of the first element in the stream that satisfies the predicate,------ /Beware/: 'findIndex' @p@ @xs@ will diverge if none of the elements of--- @xs@ satisfy @p@.-findIndex :: (a -> Bool) -> Zipper a -> Integer-findIndex p0 (n0 :~ f0) = go p0 n0 f0 - n0 where-  go !p !n !f -    | x <- f n, p x = n-    | otherwise = go p (n + 1) f---- | Internal helper, used to find an index in the -findIndex' :: (a -> Bool) -> Zipper a -> Integer-findIndex' p0 (n0 :~ f0) = go p0 n0 f0 where-  go !p !n !f -    | x <- f n, p x = n-    | otherwise = go p (n + 1) f---- | The 'elemIndex' function returns the index of the first element--- in the given stream which is equal (by '==') to the query element,------ /Beware/: @'elemIndex' x xs@ will diverge if none of the elements--- of @xs@ equal @x@.-elemIndex :: Eq a => a -> Zipper a -> Integer-elemIndex = findIndex . (==)--{---- | The 'elemIndices' function extends 'elemIndex', by returning the--- indices of all elements equal to the query element, in ascending order.------ /Beware/: 'elemIndices' @x@ @xs@ will diverge if any suffix of--- @xs@ does not contain @x@.-elemIndices :: Eq a => a -> Zipper a -> Zipper Int-elemIndices x = findIndices (x==)--}---- | The 'zip' function takes two streams and returns a list of--- corresponding pairs.------ > zip = liftA2 (,)-zip :: Zipper a -> Zipper b -> Zipper (a,b)-zip = liftA2 (,)---- | The 'zipWith' function generalizes 'zip'. Rather than tupling--- the functions, the elements are combined using the function--- passed as the first argument to 'zipWith'.------ > zipWith = liftA2-zipWith :: (a -> b -> c) -> Zipper a -> Zipper b -> Zipper c-zipWith = liftA2---- | The 'unzip' function is the inverse of the 'zip' function.-unzip :: Zipper (a,b) -> (Zipper a, Zipper b)-unzip xs = (fst <$> xs, snd <$> xs)----{----- | The 'findIndices' function extends 'findIndex', by returning the--- indices of all elements satisfying the predicate, in ascending--- order.------ /Beware/: 'findIndices' @p@ @xs@ will diverge if all the elements--- of any suffix of @xs@ fails to satisfy @p@.-findIndices :: (a -> Bool) -> Zipper a -> Zipper Int-findIndices p = indicesFrom 0 where-  indicesFrom ix (x :< xs) -    | p x = ix :< ixs -    | otherwise = ixs-    where ixs = (indicesFrom $! (ix+1)) xs----- | The 'words' function breaks a stream of characters into a--- stream of words, which were delimited by white space.------ /Beware/: if the stream of characters @xs@ does not contain white--- space, accessing the tail of @words xs@ will loop.-words :: Zipper Char -> Zipper String-words xs | (w, ys) <- break isSpace xs = w :< words ys---- | The 'unwords' function is an inverse operation to 'words'. It--- joins words with separating spaces.-unwords :: Zipper String -> Zipper Char-unwords ~(x :< xs) = foldr (:<) (' ' :< unwords xs) x---- | The 'lines' function breaks a stream of characters into a list--- of strings at newline characters. The resulting strings do not--- contain newlines.------ /Beware/: if the stream of characters @xs@ does not contain--- newline characters, accessing the tail of @lines xs@ will loop.-lines :: Zipper Char -> Zipper String-lines xs | (l, ys) <- break (== '\n') xs = l :< lines (tail ys)---- | The 'unlines' function is an inverse operation to 'lines'. It--- joins lines, after appending a terminating newline to each.-unlines :: Zipper String -> Zipper Char-unlines ~(x :< xs) = foldr (:<) ('\n' :< unlines xs) x---- | The 'fromList' converts an infinite list to a--- stream.------ /Beware/: Passing a finite list, will cause an error.-fromList :: [a] -> Zipper a-fromList (x:xs) = x :< fromList xs-fromList []     = error "Zipper.listToZipper applied to finite list"---}
− Data/Stream/Infinite/Skew.hs
@@ -1,348 +0,0 @@-{-# LANGUAGE PatternGuards, BangPatterns #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Stream.Infinite.Skew--- Copyright   :  (C) 2011 Edward Kmett,--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable------ Anticausal streams implemented as non-empty skew binary random access lists--- --- The Applicative zips streams, the monad diagonalizes----------------------------------------------------------------------------------module Data.Stream.Infinite.Skew -    ( Stream-    , (<|)      -- O(1)-    , (!!)-    , head      -- O(1)-    , tail      -- O(1)-    , tails-    , uncons    -- O(1)-    , index     -- O(log n)-    , drop      -- O(log n)-    , dropWhile -- O(n)-    , span-    , break-    , split-    , splitW-    , repeat   -    , insert    -- O(n)-    , insertBy-    , adjust    -- O(log n)-    , update    -- O(log n)-    , fromList-    , from-    , indexed-    , interleave-    , tabulate-    ) where --import Control.Arrow (first)-import Control.Applicative hiding (empty)-import Control.Comonad-import Data.Distributive-import Data.Functor.Alt-import Data.Functor.Extend-import Data.Foldable hiding (toList)-import Data.Traversable-import Data.Semigroup hiding (Last)-import Data.Semigroup.Foldable-import Data.Semigroup.Traversable-import Prelude hiding (null, head, tail, drop, dropWhile, length, foldr, last, span, repeat, replicate, (!!), break)--infixr 5 :<, <|--data Complete a -    = Tip a-    | Bin !Integer a !(Complete a) !(Complete a)-    deriving Show--instance Functor Complete where-  fmap f (Tip a) = Tip (f a)-  fmap f (Bin w a l r) = Bin w (f a) (fmap f l) (fmap f r)--instance Extend Complete where-  extended f w@Tip {} = Tip (f w)-  extended f w@(Bin n _ l r) = Bin n (f w) (extended f l) (extended f r)--instance Comonad Complete where-  extend f w@Tip {} = Tip (f w)-  extend f w@(Bin n _ l r) = Bin n (f w) (extend f l) (extend f r)-  extract (Tip a) = a-  extract (Bin _ a _ _) = a--instance Foldable Complete where-  foldMap f (Tip a) = f a -  foldMap f (Bin _ a l r) = f a `mappend` foldMap f l `mappend` foldMap f r-  foldr f z (Tip a) = f a z-  foldr f z (Bin _ a l r) = f a (foldr f (foldr f z r) l)--instance Foldable1 Complete where-  foldMap1 f (Tip a) = f a-  foldMap1 f (Bin _ a l r) = f a <> foldMap1 f l <> foldMap1 f r--instance Traversable Complete where-  traverse f (Tip a) = Tip <$> f a -  traverse f (Bin n a l r) = Bin n <$> f a <*> traverse f l <*> traverse f r--instance Traversable1 Complete where-  traverse1 f (Tip a) = Tip <$> f a -  traverse1 f (Bin n a l r) = Bin n <$> f a <.> traverse1 f l <.> traverse1 f r--bin :: a -> Complete a -> Complete a -> Complete a -bin a l r = Bin (1 + weight l + weight r) a l r-{-# INLINE bin #-}--weight :: Complete a -> Integer-weight Tip{} = 1-weight (Bin w _ _ _) = w-{-# INLINE weight #-}---- A future is a non-empty skew binary random access list of nodes.--- The last node, however, is allowed to contain fewer values. -data Stream a = !(Complete a) :< Stream a---  deriving Show--instance Show a => Show (Stream a) where-  showsPrec d as = showParen (d >= 10) $ -    showString "fromList " . showsPrec 11 (toList as)--instance Functor Stream where-  fmap f (t :< ts) = fmap f t :< fmap f ts--instance Extend Stream where-  extended = extend--instance Comonad Stream where-  extend g0 (t :< ts) = go g0 t (:< ts) :< extend g0 ts-    where-      go :: (Stream a -> b) -> Complete a -> (Complete a -> Stream a) -> Complete b-      go g w@Tip{}         f = Tip (g (f w))-      go g w@(Bin n _ l r) f = Bin n (g (f w)) (go g l (:< f r))  (go g r f)-  extract = head--instance Apply Stream where-  fs <.> as = mapWithIndex (\n f -> f (as !! n)) fs-  as <.  _  = as-  _   .> bs = bs--instance ComonadApply Stream where-  (<@>) = (<.>)-  (<@) = (<.)-  (@>) = (.>)--instance Applicative Stream where-  pure = repeat-  (<*>) = (<.>)-  (<* ) = (<. )-  ( *>) = ( .>)--instance Alt Stream where-  as <!> bs = tabulate $ \i -> case quotRem i 2 of -    (q,0) -> as !! q-    (q,_) -> bs !! q---instance Foldable Stream where-  foldMap f (t :< ts) = foldMap f t `mappend` foldMap f ts-  foldr f z (t :< ts) = foldr f (foldr f z ts) t--toList :: Stream a -> [a]-toList = foldr (:) []--instance Foldable1 Stream where-  foldMap1 f (t :< ts) = foldMap1 f t <> foldMap1 f ts--instance Traversable Stream where-  traverse f (t :< ts) = (:<) <$> traverse f t <*> traverse f ts--instance Traversable1 Stream where-  traverse1 f (t :< ts) = (:<) <$> traverse1 f t <.> traverse1 f ts--instance Distributive Stream where-  distribute w = tabulate (\i -> fmap (!! i) w)--instance Semigroup (Stream a) where-  (<>) = (<!>)--instance Monad Stream where-  return = pure-  as >>= f = mapWithIndex (\i a -> f a !! i) as--interleave :: Stream a -> Stream a -> Stream a-interleave = (<!>) -      -repeat :: a -> Stream a -repeat b = go b (Tip b) -    where -      go :: a -> Complete a -> Stream a -      go a as | ass <- bin a as as = as :< go a ass--mapWithIndex :: (Integer -> a -> b) -> Stream a -> Stream b-mapWithIndex f0 as0 = spine f0 0 as0-  where -    spine f m (a :< as) = tree f m a :< spine f (m + weight a) as-    tree f m (Tip a) = Tip (f m a)-    tree f m (Bin n a l r) = Bin n (f m a) (tree f (m + 1) l) (tree f (m + 1 + weight l) r)--tabulate :: (Integer -> a) -> Stream a-tabulate f = mapWithIndex (const . f) (pure ())---indexed :: Stream a -> Stream (Integer, a)-indexed = mapWithIndex (,)--from :: Num a => a -> Stream a-from a = mapWithIndex ((+) . fromIntegral) (pure a)---- | /O(1)/ cons-(<|) :: a -> Stream a -> Stream a-a <| (l :< r :< as) -  | weight l == weight r = bin a l r :< as-a <| as = Tip a :< as-{-# INLINE (<|) #-}---- | /O(1)/-head :: Stream a -> a-head (a :< _) = extract a-{-# INLINE head #-}---- | /O(1)/.-tail :: Stream a -> Stream a-tail (Tip{} :< ts) = ts-tail (Bin _ _ l r :< ts) = l :< r :< ts-{-# INLINE tail #-}--tails :: Stream a -> Stream (Stream a)-tails = duplicate-{-# INLINE tails #-}---- | /O(1)/.-uncons :: Stream a -> (a, Stream a)-uncons (Tip a       :< as)  = (a, as)-uncons (Bin _ a l r :< as)  = (a, l :< r :< as)-{-# INLINE uncons #-}---- | /O(log n)/.-index :: Integer -> Stream a -> a-index i (t :< ts) -  | i < 0     = error "index: negative index"-  | i < w     = indexComplete i t-  | otherwise = index (i - w) ts-  where w = weight t--indexComplete :: Integer -> Complete a -> a-indexComplete 0 (Tip a) = a-indexComplete 0 (Bin _ a _ _) = a-indexComplete i (Bin w _ l r) -  | i <= w'   = indexComplete (i-1) l-  | otherwise = indexComplete (i-1-w') r-  where w' = div w 2-indexComplete _ _ = error "indexComplete"---- | /O(log n)/.-(!!) :: Stream a -> Integer -> a-(!!) = flip index ---- | /O(log n)/.-drop :: Integer -> Stream a -> Stream a-drop 0 ts = ts-drop i (t :< ts) = case compare i w of-  LT -> dropComplete i t (:< ts)-  EQ -> ts-  GT -> drop (i - w) ts-  where w = weight t--dropComplete :: Integer -> Complete a -> (Complete a -> Stream a) -> Stream a -dropComplete 0 t f             = f t-dropComplete 1 (Bin _ _ l r) f = l :< f r-dropComplete i (Bin w _ l r) f = case compare (i - 1) w' of-    LT -> dropComplete (i-1) l (:< f r)-    EQ -> f r-    GT -> dropComplete (i-1-w') r f-    where w' = div w 2-dropComplete _ _ _ = error "dropComplete"---- /O(n)/.-dropWhile :: (a -> Bool) -> Stream a -> Stream a-dropWhile p as -  | p (head as) = dropWhile p (tail as)-  | otherwise   = as---- /O(n)/-span :: (a -> Bool) -> Stream a -> ([a], Stream a)-span p as-  | a <- head as, p a = first (a:) $ span p (tail as)-  | otherwise = ([], as)---- /O(n)/-break :: (a -> Bool) -> Stream a -> ([a], Stream a)-break p = span (not . p)---- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.--- best used with a monotonic function-split :: (a -> Bool) -> Stream a -> ([a], Stream a)-split p (a :< as)-  | p (extract as) = splitComplete p a (:< as)-  | (ts, fs) <- split p as = (foldr (:) ts a, fs)---- for use when we know the split occurs within a given tree-splitComplete :: (a -> Bool) -> Complete a -> (Complete a -> Stream a) -> ([a], Stream a)-splitComplete _ t@Tip{} f = ([], f t)-splitComplete p t@(Bin _ a l r) f-  | p a                                                   = ([], f t)-  | p (extract r), (ts, fs) <- splitComplete p l (:< f r) = (a:ts, fs)-  |                (ts, fs) <- splitComplete p r f        = (a:foldr (:) ts l, fs)---- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.--- best used with a monotonic function------ > splitW p xs = (map extract &&& fmap (fmap extract)) . split p . duplicate-splitW :: (Stream a -> Bool) -> Stream a -> ([a], Stream a)-splitW p (a :< as) -  | p as                    = splitCompleteW p a (:< as)-  | (ts, fs) <- splitW p as = (foldr (:) ts a, fs)---- for use when we know the split occurs within a given tree-splitCompleteW :: (Stream a -> Bool) -> Complete a -> (Complete a -> Stream a) -> ([a], Stream a)-splitCompleteW _ t@Tip{} f = ([], f t)-splitCompleteW p t@(Bin _ a l r) f-  | w <- f t, p w                                        = ([], w)-  | w <- f r, p w, (ts, fs) <- splitCompleteW p l (:< w) = (a:ts, fs)-  |                (ts, fs) <- splitCompleteW p r f      = (a:foldr (:) ts l, fs)--fromList :: [a] -> Stream a-fromList = foldr (<|) (error "fromList: finite list")---- /O(n)/-insert :: Ord a => a -> Stream a -> Stream a-insert a as | (ts, as') <- split (a<=) as = foldr (<|) (a <| as') ts---- /O(n)/. Finds the split in O(log n), but then has to recons-insertBy :: (a -> a -> Ordering) -> a -> Stream a -> Stream a-insertBy cmp a as | (ts, as') <- split (\b -> cmp a b <= EQ) as = foldr (<|) (a <| as') ts---- /O(log n)/ Change the value of the nth entry in the future-adjust :: Integer -> (a -> a) -> Stream a -> Stream a-adjust !n f (a :< as) -  | n < w = adjustComplete n f a :< as-  | otherwise = a :< adjust (n - w) f as-  where w = weight a--adjustComplete :: Integer -> (a -> a) -> Complete a -> Complete a-adjustComplete 0 f (Tip a) = Tip (f a)-adjustComplete _ _ t@Tip{} = t-adjustComplete n f (Bin m a l r) -  | n == 0 = Bin m (f a) l r-  | n < w = Bin m a (adjustComplete (n - 1) f l) r-  | otherwise = Bin m a l (adjustComplete (n - 1 - w) f r)-  where w = weight l--update :: Integer -> a -> Stream a -> Stream a-update n = adjust n . const-
− Data/Stream/Supply.hs
@@ -1,174 +0,0 @@-{-# LANGUAGE CPP, FlexibleContexts #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Stream.Supply--- Copyright   :  (C) 2008-2011 Edward Kmett,---                (C) 2008 Iavor S. Diatchki--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable------ This library can be used to generate values (for example, new names)--- without the need to thread state.  This means that functions that--- need to generate new values only need a supply object as an argument,--- and they do not need to return a new supply object as a result.--- This decreases the number of data-dependencies in a program, which--- makes it easier to exploit parallelism.------ The technique for generating new values is based on the paper--- ''On Generating Unique Names'' by Lennart Augustsson, Mikael Rittri, --- and Dan Synek.------------------------------------------------------------------------------module Data.Stream.Supply-  ( Supply-  , newSupply-  , newEnumSupply-  , newNumSupply-  , newDupableSupply-  , newDupableEnumSupply-  , newDupableNumSupply-  , leftSupply-  , rightSupply-  , split-  , splits-  , splitSkew-  , split2-  , split3-  , split4-  ) where--import Control.Applicative-import Control.Comonad-import Data.Functor.Apply-import Data.Functor.Extend-import Data.Foldable-import Data.IORef(newIORef, atomicModifyIORef)-import Data.Traversable-import Data.Semigroup-import Data.Semigroup.Foldable-import Data.Semigroup.Traversable-import System.IO.Unsafe (unsafeInterleaveIO)-import Data.Stream.Infinite-import qualified Data.Stream.Infinite.Skew as Skew--#ifdef LANGUAGE_DeriveDataTypeable-import Data.Data-#endif--#ifdef __GLASGOW_HASKELL__ >= 608 -import GHC.IO(unsafeDupableInterleaveIO)-#else-unsafeDupableInterleaveIO :: IO a -> IO a-unsafeDupableInterleaveIO = unsafeInterleaveIO-#endif--data Supply a = Supply a (Supply a) (Supply a) deriving -  ( Show, Read, Eq, Ord-#ifdef LANGUAGE_DeriveDataTypeable-  , Data, Typeable-#endif-  )--instance Functor Supply where-  fmap f (Supply a l r) = Supply (f a) (fmap f l) (fmap f r)-  a <$ _ = pure a--instance Extend Supply where-  extended f s@(Supply _ l r) = Supply (f s) (extended f l) (extended f r)-  duplicated s@(Supply _ l r) = Supply s (duplicated l) (duplicated r)--instance Comonad Supply where-  extend f s@(Supply _ l r) = Supply (f s) (extend f l) (extend f r)-  duplicate s@(Supply _ l r) = Supply s (duplicate l) (duplicate r)-  extract (Supply a _ _) = a--instance Apply Supply where-  Supply f fl fr <.> Supply a al ar = Supply (f a) (fl <.> al) (fr <.> ar)-  a <. _ = a-  _ .> a = a--instance Applicative Supply where-  pure a = as where as = Supply a as as-  Supply f fl fr <*> Supply a al ar = Supply (f a) (fl <*> al) (fr <*> ar)-  a <* _ = a-  _ *> a = a--instance Foldable Supply where-  foldMap f (Supply a l r) = f a `mappend` foldMap f l `mappend` foldMap f r--instance Foldable1 Supply where-  foldMap1 f (Supply a l r) = f a <> foldMap1 f l <> foldMap1 f r--instance Traversable Supply where-  traverse f (Supply a l r) = Supply <$> f a <*> traverse f l <*> traverse f r--instance Traversable1 Supply where-  traverse1 f (Supply a l r) = Supply <$> f a <.> traverse1 f l <.> traverse1 f r-  -leftSupply :: Supply a -> Supply a-leftSupply (Supply _ l _) = l--rightSupply :: Supply a -> Supply a-rightSupply (Supply _ _ r) = r---- unfoldsW :: (Comonad w, Functor f) => (w a -> (b, f a)) -> w a -> StreamT f w b-newSupply :: (a -> a) -> a -> IO (Supply a)-newSupply f x = gen =<< newIORef x-  where gen r = unsafeInterleaveIO $-          Supply <$> unsafeInterleaveIO (atomicModifyIORef r update) -                 <*> gen r -                 <*> gen r-        update a = b `seq` (b, a) where b = f a-{-# INLINE newSupply #-}--newDupableSupply :: (a -> a) -> a -> IO (Supply a)-newDupableSupply f x = gen =<< newIORef x-  where gen r = unsafeDupableInterleaveIO $-          Supply <$> unsafeDupableInterleaveIO (atomicModifyIORef r update)-                 <*> gen r-                 <*> gen r-        update a = b `seq` (b, a) where b = f a-{-# INLINE newDupableSupply #-}--newEnumSupply :: Enum a => IO (Supply a)-newEnumSupply = newSupply succ (toEnum 0)-{-# SPECIALIZE newEnumSupply :: IO (Supply Int) #-}--newNumSupply :: Num a => IO (Supply a)-newNumSupply = newSupply (1+) 0-{-# SPECIALIZE newNumSupply :: IO (Supply Int) #-}--newDupableEnumSupply :: Enum a => IO (Supply a)-newDupableEnumSupply = newSupply succ (toEnum 0)-{-# SPECIALIZE newEnumSupply :: IO (Supply Int) #-}--newDupableNumSupply :: Num a => IO (Supply a)-newDupableNumSupply = newSupply (1+) 0-{-# SPECIALIZE newNumSupply :: IO (Supply Int) #-}--split :: Supply a -> Stream (Supply a)-split (Supply _ l r) = l :> split r--splits :: Integral b => Supply a -> b -> Supply a-splits (Supply _ l r) n = case n `quotRem` 2 of-  (0,0)  -> leftSupply l-  (q,-1) -> splits (rightSupply l) q-  (q,0)  -> splits (leftSupply r) q-  (q,1)  -> splits (rightSupply r) q-  (_,_)  -> error "quotRem: impossible result"-{-# SPECIALIZE splits :: Supply a -> Int -> Supply a #-}-{-# SPECIALIZE splits :: Supply a -> Integer -> Supply a #-}--splitSkew :: Supply a -> Skew.Stream (Supply a)-splitSkew = Skew.tabulate . splits--split2 :: Supply a -> (Supply a, Supply a)-split2 (Supply _ l r) = (l, r)--split3 :: Supply a -> (Supply a, Supply a, Supply a)-split3 (Supply _ a (Supply _ b c)) = (a, b, c)--split4 :: Supply a -> (Supply a, Supply a, Supply a, Supply a)-split4 (Supply _ (Supply _ a b) (Supply _ c d)) = (a, b, c, d)
README view
@@ -34,7 +34,7 @@ Data.Stream.Infinite.Functional.Causal           data Causal a = Causal !(Integer -> a) !Integer -- decrement only  Data.Sequence.Future        data Future a = Future !(Int# -> a)      Int# Int#-Data.Sequence.Causal        data Causal a = Causal !(Int# -> a) Int# Int#     +Data.Sequence.Causal        data Causal a = Causal !(Int# -> a) Int# Int# Data.Sequence.Zipper        data Zipper a = Zipper !(Int# -> a) Int# Int# Int#  Data.Tensors          data Tensors f a = Last a | a :-   Tensors f (f a)
+ src/Data/Stream/Future.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE BangPatterns #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Stream.Future+-- Copyright   :  (C) 2011 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+----------------------------------------------------------------------------++module Data.Stream.Future+  ( Future(..)+  , cons, (<|)+  , head+  , tail+  , length+  , tails+  , map+  , index+  ) where++import Prelude hiding (head, tail, map, length)+import Control.Applicative+import Control.Comonad+import Data.Foldable+import Data.Functor.Alt+import Data.Functor.Extend+import Data.Traversable+import Data.Semigroup hiding (Last)+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+#ifdef LANGUAGE_DeriveDataTypeable+import Data.Data+#endif++infixr 5 :<, <|++data Future a = Last a | a :< Future a deriving+  ( Eq, Ord, Show, Read+#ifdef LANGUAGE_DeriveDataTypeable+  , Data, Typeable+#endif+  )++(<|) :: a -> Future a -> Future a+(<|) = (:<)+{-# INLINE (<|) #-}++cons :: a -> Future a -> Future a+cons = (:<)+{-# INLINE cons #-}++head :: Future a -> a+head (Last a) = a+head (a :< _) = a+{-# INLINE head #-}++length :: Future a -> Int+length = go 1+  where+    go !n (Last _)  = n+    go !n (_ :< as) = go (n + 1) as+{-# INLINE length #-}++tail :: Future a -> Maybe (Future a)+tail (Last _) = Nothing+tail (_ :< as) = Just as+{-# INLINE tail #-}++tails :: Future a -> Future (Future a)+tails w@(_ :< as) = w :< tails as+tails w@(Last _)  = Last w+{-# INLINE tails #-}++map :: (a -> b) -> Future a -> Future b+map f (a :< as) = f a :< map f as+map f (Last a)  = Last (f a)+{-# INLINE map #-}++index :: Int -> Future a -> a+index n aas+  | n < 0 = error "index: negative index"+  | n == 0 = extract aas+  | otherwise = case aas of+    Last _ -> error "index: out of range"+    _ :< as -> index (n - 1) as++instance Functor Future where+  fmap = map+  b <$ (_ :< as) = b :< (b <$ as)+  b <$ _         = Last b++instance Foldable Future where+  foldMap = foldMapDefault++instance Traversable Future where+  traverse f (Last a)  = Last <$> f a+  traverse f (a :< as) = (:<) <$> f a <*> traverse f as++instance Foldable1 Future++instance Traversable1 Future where+  traverse1 f (Last a)  = Last <$> f a+  traverse1 f (a :< as) = (:<) <$> f a <.> traverse1 f as++instance Extend Future where+  extended = extend++instance Comonad Future where+  extract = head+  duplicate = tails+  extend f w@(_ :< as) = f w :< extend f as+  extend f w@(Last _)  = Last (f w)++instance Apply Future where+  Last f    <.> Last a    = Last (f a)+  (f :< _)  <.> Last a    = Last (f a)+  Last f    <.> (a :< _ ) = Last (f a)+  (f :< fs) <.> (a :< as) = f a :< (fs <.> as)++  Last a    <. _         = Last a+  (a :< _ ) <. Last _    = Last a+  (a :< as) <. (_ :< bs) = a :< (as <. bs)++  _          .> Last b   = Last b+  Last _     .> (b :< _) = Last b+  (_ :< as)  .> (b :< bs) = b :< (as .> bs)++instance ComonadApply Future where+  (<@>) = (<.>)++instance Alt Future where+  Last a    <!> bs = a :< bs+  (a :< as) <!> bs = a :< (as <!> bs)++instance Semigroup (Future a) where+  (<>) = (<!>)++instance Applicative Future where+  pure = Last+  (<*>) = (<.>)+  (<* ) = (<. )+  ( *>) = ( .>)++
+ src/Data/Stream/Future/Skew.hs view
@@ -0,0 +1,426 @@+{-# LANGUAGE PatternGuards, BangPatterns #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Stream.Future.Skew+-- Copyright   :  (C) 2008-2011 Edward Kmett,+--                (C) 2004 Dave Menendez+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Anticausal streams implemented as non-empty skew binary random access lists+--+-- The Applicative zips streams, but since these are potentially infinite+-- this is stricter than would be desired. You almost always want+------------------------------------------------------------------------------+++module Data.Stream.Future.Skew+    ( Future(..)+    , (<|)      -- O(1)+    , cons+    , length    -- O(log n)+    , head      -- O(1)+    , tail      -- O(1)+    , tails+    , last      -- O(log n)+    , uncons    -- O(1)+    , index     -- O(log n)+    , drop      -- O(log n)+    , dropWhile -- O(n)+    , indexed+    , from+    , break+    , span+    , split     -- O(log n)+    , splitW    -- O(log n)+    , repeat+    , replicate -- O(log n)+    , insert    -- O(n)+    , insertBy+    , update+    , adjust    -- O(log n)+    , fromList+    , toFuture+    ) where++import Control.Applicative hiding (empty)+import Control.Comonad+import Data.Functor.Alt+import Data.Functor.Extend+import Data.Foldable hiding (toList)+import Data.Traversable (Traversable, traverse)+import Data.Semigroup hiding (Last)+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Prelude hiding (null, head, tail, drop, dropWhile, length, foldr, last, span, repeat, replicate, break)++infixr 5 :<, <|++data Complete a+    = Tip a+    | Bin {-# UNPACK #-} !Int a !(Complete a) !(Complete a)+    deriving Show++instance Functor Complete where+  fmap f (Tip a) = Tip (f a)+  fmap f (Bin w a l r) = Bin w (f a) (fmap f l) (fmap f r)++instance Extend Complete where+  extended = extend++instance Comonad Complete where+  extend f w@Tip {} = Tip (f w)+  extend f w@(Bin n _ l r) = Bin n (f w) (extend f l) (extend f r)+  extract (Tip a) = a+  extract (Bin _ a _ _) = a++instance Foldable Complete where+  foldMap f (Tip a) = f a+  foldMap f (Bin _ a l r) = f a `mappend` foldMap f l `mappend` foldMap f r+  foldr f z (Tip a) = f a z+  foldr f z (Bin _ a l r) = f a (foldr f (foldr f z r) l)++instance Foldable1 Complete where+  foldMap1 f (Tip a) = f a+  foldMap1 f (Bin _ a l r) = f a <> foldMap1 f l <> foldMap1 f r++instance Traversable Complete where+  traverse f (Tip a) = Tip <$> f a+  traverse f (Bin n a l r) = Bin n <$> f a <*> traverse f l <*> traverse f r++instance Traversable1 Complete where+  traverse1 f (Tip a) = Tip <$> f a+  traverse1 f (Bin n a l r) = Bin n <$> f a <.> traverse1 f l <.> traverse1 f r++bin :: a -> Complete a -> Complete a -> Complete a+bin a l r = Bin (1 + weight l + weight r) a l r+{-# INLINE bin #-}++weight :: Complete a -> Int+weight Tip{} = 1+weight (Bin w _ _ _) = w+{-# INLINE weight #-}++-- A future is a non-empty skew binary random access list of nodes.+-- The last node, however, is allowed to contain fewer values.+data Future a+  = Last !(Complete a)+  | !(Complete a) :< Future a+--  deriving Show+++instance Show a => Show (Future a) where+  showsPrec d as = showParen (d >= 10) $+    showString "fromList " . showsPrec 11 (toList as)++instance Functor Future where+  fmap f (t :< ts) = fmap f t :< fmap f ts+  fmap f (Last t) = Last (fmap f t)++instance Extend Future where+  extended = extend++instance Comonad Future where+  extend g (Last t)  = Last (extendTree g t Last)+  extend g (t :< ts) = extendTree g t (:< ts) :< extend g ts+  extract = head++extendTree :: (Future a -> b) -> Complete a -> (Complete a -> Future a) -> Complete b+extendTree g w@Tip{}         f = Tip (g (f w))+extendTree g w@(Bin n _ l r) f = Bin n (g (f w)) (extendTree g l (:< f r))  (extendTree g r f)++instance Apply Future where+  Last (Tip f)         <.> as                   = singleton (f (extract as))+  fs                   <.> Last (Tip a)         = singleton (extract fs a)+  Last (Bin _ f lf rf) <.> Last (Bin _ a la ra) = f a <| (lf :< Last rf  <.> la :< Last ra )+  Last (Bin _ f lf rf) <.> Bin _ a la ra :< as  = f a <| (lf :< Last rf  <.> la :< ra :< as)+  Last (Bin _ f lf rf) <.> Tip a :< as          = f a <| (lf :< Last rf  <.> as            )+  Bin _ f lf rf :< fs  <.> Last (Bin _ a la ra) = f a <| (lf :< rf :< fs <.> la :< Last ra )+  Bin _ f lf rf :< fs  <.> Tip a :< as          = f a <| (lf :< rf :< fs <.> as            )+  Bin _ f lf rf :< fs  <.> Bin _ a la ra :< as  = f a <| (lf :< rf :< fs <.> la :< ra :< as)+  Tip f :< fs          <.> Tip a :< as          = f a <| (fs             <.> as            )+  Tip f :< fs          <.> Bin _ a la ra :< as  = f a <| (fs             <.> la :< ra :< as)+  Tip f :< fs          <.> Last (Bin _ a la ra) = f a <| (fs             <.> la :< Last ra )++instance ComonadApply Future where+  (<@>) = (<.>)++instance Applicative Future where+  pure = repeat+  (<*>) = (<.>)++instance Alt Future where+  as <!> bs = foldr (<|) bs as++instance Foldable Future where+  foldMap f (t :< ts) = foldMap f t `mappend` foldMap f ts+  foldMap f (Last t) = foldMap f t+  foldr f z (t :< ts) = foldr f (foldr f z ts) t+  foldr f z (Last t) = foldr f z t++toList :: Future a -> [a]+toList = foldr (:) []++instance Foldable1 Future where+  foldMap1 f (t :< ts) = foldMap1 f t <> foldMap1 f ts+  foldMap1 f (Last t) = foldMap1 f t++instance Traversable Future where+  traverse f (t :< ts) = (:<) <$> traverse f t <*> traverse f ts+  traverse f (Last t) = Last <$> traverse f t++instance Traversable1 Future where+  traverse1 f (t :< ts) = (:<) <$> traverse1 f t <.> traverse1 f ts+  traverse1 f (Last t) = Last <$> traverse1 f t++repeat :: a -> Future a+repeat a0 = go a0 (Tip a0)+    where+      go :: a -> Complete a -> Future a+      go a as | ass <- bin a as as = as :< go a ass+{-# INLINE repeat #-}++-- | /O(log n)/+replicate :: Int -> a -> Future a+replicate n a+  | n <= 0    = error "replicate: non-positive argument"+  | otherwise = go 1 n a (Tip a) (\ _ r -> r)+  where+  -- invariants:+  -- tb is a complete tree of i nodes all equal to b+  -- 1 <= i = 2^m-1 <= j+  -- k accepts r such that 0 <= r < i+  go :: Int -> Int -> b -> Complete b -> (Int -> Future b -> r) -> r+  go !i !j b tb k+    | j >= i2p1 = go i2p1 j b (Bin i2p1 b tb tb) k'+    | j >= i2   = k (j - i2) (tb :< Last tb)+    | otherwise = k (j - i) (Last tb)+    where+      i2 = i * 2+      i2p1 = i2 + 1+      k' r xs+        | r >= i2   = k (r - i2) (tb :< tb :< xs)+        | r >= i    = k (r - i) (tb :< xs)+        | otherwise = k r xs+{-# INLINE replicate #-}++mapWithIndex :: (Int -> a -> b) -> Future a -> Future b+mapWithIndex f0 as0 = spine f0 0 as0+  where+    spine f m (Last as) = Last (tree f m as)+    spine f m (a :< as) = tree f m a :< spine f (m + weight a) as+    tree f m (Tip a) = Tip (f m a)+    tree f m (Bin n a l r) = Bin n (f m a) (tree f (m + 1) l) (tree f (m + 1 + weight l) r)++indexed :: Future a -> Future (Int, a)+indexed = mapWithIndex (,)+{-# INLINE indexed #-}++from :: Num a => a -> Future a+from a = mapWithIndex ((+) . fromIntegral) (pure a)+{-# INLINE from #-}++-- | /O(1)/+singleton :: a -> Future a+singleton a = Last (Tip a)+{-# INLINE singleton #-}++-- | /O(log n)/.+length :: Future a -> Int+length (Last t) = weight t+length (t :< ts) = weight t + length ts++-- | /O(1)/ cons+(<|) :: a -> Future a -> Future a+a <| (l :< Last r)+  | weight l == weight r = Last (bin a l r)+a <| (l :< r :< as)+  | weight l == weight r = bin a l r :< as+a <| as = Tip a :< as+{-# INLINE (<|) #-}+++cons :: a -> Future a -> Future a+cons = (<|)+{-# INLINE cons #-}++-- | /O(1)/+head :: Future a -> a+head (a :< _) = extract a+head (Last a) = extract a+{-# INLINE head #-}++-- | /O(1)/.+tail :: Future a -> Maybe (Future a)+tail (Tip{} :< ts) = Just ts+tail (Bin _ _ l r :< ts) = Just (l :< r :< ts)+tail (Last Tip{}) = Nothing+tail (Last (Bin _ _ l r)) = Just (l :< Last r)+{-# INLINE tail #-}++tails :: Future a -> Future (Future a)+tails = duplicate+{-# INLINE tails #-}++-- | /O(log n)/.+last :: Future a -> a+last (_ :< as) = last as+last (Last as) = go as+  where go (Tip a) = a+        go (Bin _ _ _ r) = go r++-- | /O(1)/.+uncons :: Future a -> (a, Maybe (Future a))+uncons (Last (Tip a))       = (a, Nothing)+uncons (Last (Bin _ a l r)) = (a, Just (l :< Last r))+uncons (Tip a       :< as)  = (a, Just as)+uncons (Bin _ a l r :< as)  = (a, Just (l :< r :< as))+{-# INLINE uncons #-}++-- | /O(log n)/.+index :: Int -> Future a -> a+index i (Last t)+  | i < weight t = indexComplete i t+  | otherwise    = error "index: out of range"+index i (t :< ts)+  | i < w     = indexComplete i t+  | otherwise = index (i - w) ts+  where w = weight t++indexComplete :: Int -> Complete a -> a+indexComplete 0 (Tip a) = a+indexComplete i (Bin w a l r)+  | i == 0    = a+  | i <= w'   = indexComplete (i-1) l+  | otherwise = indexComplete (i-1-w') r+  where w' = div w 2+indexComplete _ _ = error "index: index out of range"++-- | /O(log n)/.+drop :: Int -> Future a -> Maybe (Future a)+drop 0 ts = Just ts+drop i (t :< ts) = case compare i w of+  LT -> Just (dropComplete i t (:< ts))+  EQ -> Just ts+  GT -> drop (i - w) ts+  where w = weight t+drop i (Last t)+  | i < w     = Just (dropComplete i t Last)+  | otherwise = Nothing+  where w = weight t++dropComplete :: Int -> Complete a -> (Complete a -> Future a) -> Future a+dropComplete 0 t f             = f t+dropComplete 1 (Bin _ _ l r) f = l :< f r+dropComplete i (Bin w _ l r) f = case compare (i - 1) w' of+  LT -> dropComplete (i-1) l (:< f r)+  EQ -> f r+  GT -> dropComplete (i-1-w') r f+  where w' = div w 2+dropComplete _ _ _ = error "drop: index out of range"++-- /O(n)/.+dropWhile :: (a -> Bool) -> Future a -> Maybe (Future a)+dropWhile p as+  | p (head as) = tail as >>= dropWhile p+  | otherwise = Just as++-- /O(n)/+span :: (a -> Bool) -> Future a -> ([a], Maybe (Future a))+span p aas = case uncons aas of+  (a, Just as) | p a, (ts, fs) <- span p as -> (a:ts, fs)+  (a, Nothing) | p a                        -> ([a], Nothing)+  (_, _)                                    -> ([], Just aas)++-- /O(n)/+break :: (a -> Bool) -> Future a -> ([a], Maybe (Future a))+break p = span (not . p)++-- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.+-- best used with a monotonic function+split :: (a -> Bool) -> Future a -> ([a], Maybe (Future a))+split p l@(Last a)+  | p (extract a)  = ([], Just l)+  | otherwise      = splitComplete p a Last+split p (a :< as)+  | p (extract as) = splitComplete p a (:< as)+  | (ts, fs) <- split p as = (foldr (:) ts a, fs)++-- for use when we know the split occurs within a given tree+splitComplete :: (a -> Bool) -> Complete a -> (Complete a -> Future a) -> ([a], Maybe (Future a))+splitComplete p t@(Tip a) f+  | p a       = ([], Just (f t))+  | otherwise = ([a], Nothing)+splitComplete p t@(Bin _ a l r) f+  | p a                                               = ([], Just (f t))+  | p (extract r), (ts, fs) <- splitComplete p l (:< f r) = (a:ts, fs)+  |                (ts, fs) <- splitComplete p r f        = (a:foldr (:) ts l, fs)++-- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.+-- best used with a monotonic function+--+-- > splitW p xs = (map extract &&& fmap (fmap extract)) . split p . duplicate+splitW :: (Future a -> Bool) -> Future a -> ([a], Maybe (Future a))+splitW p l@(Last a)+  | p l       = ([], Just l)+  | otherwise = splitCompleteW p a Last+splitW p (a :< as)+  | p as                    = splitCompleteW p a (:< as)+  | (ts, fs) <- splitW p as = (foldr (:) ts a, fs)++-- for use when we know the split occurs within a given tree+splitCompleteW :: (Future a -> Bool) -> Complete a -> (Complete a -> Future a) -> ([a], Maybe (Future a))+splitCompleteW p t@(Tip a) f+  | w <- f t, p w = ([], Just w)+  | otherwise = ([a], Nothing)+splitCompleteW p t@(Bin _ a l r) f+  | w <- f t, p w                                    = ([], Just w)+  | w <- f r, p w, (ts, fs) <- splitCompleteW p l (:< w) = (a:ts, fs)+  |                (ts, fs) <- splitCompleteW p r f      = (a:foldr (:) ts l, fs)++fromList :: [a] -> Future a+fromList [] = error "fromList: empty list"+fromList (x:xs) = go x xs+  where go a [] = singleton a+        go a (b:bs) = a <| go b bs++toFuture :: [a] -> Maybe (Future a)+toFuture [] = Nothing+toFuture xs = Just (fromList xs)++-- /O(n)/+insert :: Ord a => a -> Future a -> Future a+insert a as = case split (a<=) as of+    (_, Nothing)  -> foldr (<|) (singleton a) as+    (ts, Just as') -> foldr (<|) (a <| as') ts++-- /O(n)/. Finds the split in O(log n), but then has to recons+insertBy :: (a -> a -> Ordering) -> a -> Future a -> Future a+insertBy cmp a as = case split (\b -> cmp a b <= EQ) as of+    (_, Nothing)  -> foldr (<|) (singleton a) as+    (ts, Just as') -> foldr (<|) (a <| as') ts++-- /O(log n)/ Change the value of the nth entry in the future+adjust :: Int -> (a -> a) -> Future a -> Future a+adjust !n f d@(Last a)+  | n < weight a = Last (adjustComplete n f a)+  | otherwise = d+adjust !n f (a :< as)+  | n < w = adjustComplete n f a :< as+  | otherwise = a :< adjust (n - w) f as+  where w = weight a++adjustComplete :: Int -> (a -> a) -> Complete a -> Complete a+adjustComplete 0 f (Tip a) = Tip (f a)+adjustComplete _ _ t@Tip{} = t+adjustComplete n f (Bin m a l r)+  | n == 0 = Bin m (f a) l r+  | n < w = Bin m a (adjustComplete (n - 1) f l) r+  | otherwise = Bin m a l (adjustComplete (n - 1 - w) f r)+  where w = weight l++update :: Int -> a -> Future a -> Future a+update n = adjust n . const
+ src/Data/Stream/Infinite.hs view
@@ -0,0 +1,455 @@+{-# LANGUAGE PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Stream.Infinite+-- Copyright   :  (C) 2011 Edward Kmett,+--                (C) 2007-2010 Wouter Swierstra, Bas van Dijk+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable (Haskell 2010)+--+----------------------------------------------------------------------------+module Data.Stream.Infinite (+   -- * The type of streams+     Stream(..)+   -- * Basic functions+   , head   -- :: Stream a -> a+   , tail   -- :: Stream a -> Stream a+   , inits  -- :: Stream a -> Stream [a]+   , tails  -- :: Stream a -> Stream (Stream a)+   -- * Stream transformations+   , map         -- :: (a -> b) -> Stream a -> Stream b+   , intersperse -- :: a -> Stream a -> Stream+   , interleave  -- :: Stream a -> Stream a -> Stream a+   , scanl       -- :: (b -> a -> b) -> b -> Stream a -> Stream b+   , scanl'      -- :: (b -> a -> b) -> b -> Stream a -> Stream b+   , scanl1      -- :: (a -> a -> a) -> Stream a -> Stream a+   , scanl1'     -- :: (a -> a -> a) -> Stream a -> Stream a+   , transpose   -- :: Stream (Stream a) -> Stream (Stream a)+   -- * Building streams+   , iterate     -- :: (a -> a) -> a -> Stream a+   , repeat      -- :: a -> Stream a+   , cycle       -- :: NonEmpty a -> Stream a+   , unfold      -- :: (a -> (b, a)) -> a -> Stream b+   -- * Extracting sublists+   , take        -- :: Int -> Stream a -> [a]+   , drop        -- :: Int -> Stream a -> Stream a+   , splitAt     -- :: Int -> Stream a -> ([a],Stream a)+   , takeWhile   -- :: (a -> Bool) -> Stream a -> [a]+   , dropWhile   -- :: (a -> Bool) -> Stream a -> Stream a+   , span        -- :: (a -> Bool) -> Stream a -> ([a], Stream a)+   , break       -- :: (a -> Bool) -> Stream a -> ([a], Stream a)+   , filter      -- :: (a -> Bool) -> Stream a -> Stream a+   , partition   -- :: (a -> Bool) -> Stream a -> (Stream a, Stream a)+   , group       -- :: (a -> Bool) -> Stream a -> Stream (NonEmpty a)+   , groupBy     -- :: (a -> a -> Bool) -> Stream a -> Stream (NonEmpty a)+   -- * Sublist predicates+   , isPrefixOf  -- :: [a] -> Stream a -> Bool+   -- * Indexing streams +   , (!!)        -- :: Int -> Stream a -> a+   , elemIndex   -- :: Eq a => a -> Stream a -> Int+   , elemIndices -- :: Eq a => a -> Stream a -> Stream Int+   , findIndex   -- :: (a -> Bool) -> Stream a -> Int+   , findIndices -- :: (a -> Bool) -> Stream a -> Stream Int+   -- * Zipping and unzipping streams+   , zip         -- :: Stream a -> Stream b -> Stream (a, b)+   , zipWith     -- :: (a -> b -> c) -> Stream a -> Stream b -> Stream c+   , unzip       -- :: Functor f => f (a, b) -> (f a, f b)+   -- * Functions on streams of characters+   , words       -- :: Stream Char -> Stream String+   , unwords     -- :: Stream String -> Stream Char+   , lines       -- :: Stream Char -> Stream String+   , unlines     -- :: Stream String -> Stream Char+   -- * Converting to and from an infinite list+   , fromList    -- :: [a] -> Stream a+   ) where++import Prelude hiding +  ( head, tail, map, scanr, scanr1, scanl, scanl1+  , iterate, take, drop, takeWhile+  , dropWhile, repeat, cycle, filter+  , (!!), zip, unzip, zipWith, words+  , unwords, lines, unlines, break, span+  , splitAt, foldr+  )++import Control.Applicative+import Control.Comonad+import Data.Char (isSpace)+import Data.Data+import Data.Functor.Apply+import Data.Functor.Extend+import Data.Semigroup+import Data.Foldable+import Data.Traversable+import Data.Distributive+import Data.Semigroup.Traversable+import Data.Semigroup.Foldable+import Data.List.NonEmpty (NonEmpty(..))++data Stream a = a :> Stream a deriving +  ( Show+#ifdef LANGUAGE_DeriveDataTypeable+  , Data, Typeable+#endif+  )++infixr 5 :>++-- | Map a pure function over a stream+map :: (a -> b) -> Stream a -> Stream b+map f (a :> as) = f a :> map f as++instance Functor Stream where+  fmap = map+  b <$ _ = repeat b++instance Distributive Stream where+  distribute w = fmap head w :> distribute (fmap tail w)++-- | Extract the first element of the sequence.+head :: Stream a -> a+head (a :> _) = a+{-# INLINE head #-}++-- | Extract the sequence following the head of the stream.+tail :: Stream a -> Stream a+tail (_ :> as) = as+{-# INLINE tail #-}++-- | The 'tails' function takes a stream @xs@ and returns all the+-- suffixes of @xs@.+tails :: Stream a -> Stream (Stream a)+tails w = w :> tails (tail w)++instance Extend Stream where+  duplicated = tails+  extended f w = f w :> extended f (tail w)++instance Comonad Stream where+  duplicate = tails+  extend f w = f w :> extend f (tail w)+  extract = head++instance Apply Stream where+  (f :> fs) <.> (a :> as) = f a :> (fs <.> as)+  as        <.  _         = as+  _          .> bs        = bs++instance ComonadApply Stream where+  (f :> fs) <@> (a :> as) = f a :> (fs <@> as)+  as        <@  _         = as+  _          @> bs        = bs++-- | 'repeat' @x@ returns a constant stream, where all elements are+-- equal to @x@.+repeat :: a -> Stream a+repeat a = as where as = a :> as++instance Applicative Stream where+  pure = repeat+  (<*>) = (<.>)+  (<* ) = (<. )+  ( *>) = ( .>)++instance Foldable Stream where+  fold (m :> ms) = m `mappend` fold ms+  foldMap f (a :> as) = f a `mappend` foldMap f as+  foldr f0 _ = go f0 where go f (a :> as) = f a (go f as)++instance Traversable Stream where+  traverse f ~(a :> as) = (:>) <$> f a <*> traverse f as++instance Foldable1 Stream++instance Traversable1 Stream where+  traverse1 f ~(a :> as) = (:>) <$> f a <.> traverse1 f as+  sequence1 ~(a :> as) = (:>) <$> a <.> sequence1 as++-- | The unfold function is similar to the unfold for lists. Note+-- there is no base case: all streams must be infinite.+unfold :: (a -> (b, a)) -> a -> Stream b+unfold f c | (x, d) <- f c = x :> unfold f d++instance Monad Stream where+  return = repeat+  m >>= f = unfold (\(bs :> bss) -> (head bs, tail <$> bss)) (fmap f m)+  _ >> bs = bs++-- | Interleave two Streams @xs@ and @ys@, alternating elements+-- from each list.+--+-- > [x1,x2,...] `interleave` [y1,y2,...] == [x1,y1,x2,y2,...]+interleave :: Stream a -> Stream a -> Stream a+interleave ~(x :> xs) ys = x :> interleave ys xs++instance Semigroup (Stream a) where+  (<>) = interleave++-- | The 'inits' function takes a stream @xs@ and returns all the+-- finite prefixes of @xs@.+--+-- Note that this 'inits' is lazier then @Data.List.inits@:+--+-- > inits _|_ = [] ::: _|_+--+-- while for @Data.List.inits@:+--+-- > inits _|_ = _|_+inits :: Stream a -> Stream [a]+inits xs = [] :> ((head xs :) <$> inits (tail xs))++-- | @'intersperse' y xs@ creates an alternating stream of+-- elements from @xs@ and @y@.+intersperse :: a -> Stream a -> Stream a+intersperse y ~(x :> xs) = x :> y :> intersperse y xs++-- | 'scanl' yields a stream of successive reduced values from:+--+-- > scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]+scanl :: (a -> b -> a) -> a -> Stream b -> Stream a+scanl f z ~(x :> xs) = z :> scanl f (f z x) xs++-- | 'scanl' yields a stream of successive reduced values from:+--+-- > scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]+scanl' :: (a -> b -> a) -> a -> Stream b -> Stream a+scanl' f z ~(x :> xs) = z :> (scanl' f $! f z x) xs++-- | 'scanl1' is a variant of 'scanl' that has no starting value argument:+--+-- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...]+scanl1 :: (a -> a -> a) -> Stream a -> Stream a+scanl1 f ~(x :> xs) = scanl f x xs++-- | @scanl1'@ is a strict 'scanl' that has no starting value.+scanl1' :: (a -> a -> a) -> Stream a -> Stream a+scanl1' f ~(x :> xs) = scanl' f x xs++-- | 'transpose' computes the transposition of a stream of streams.+transpose :: Stream (Stream a) -> Stream (Stream a)+transpose ~((x :> xs) :> yss) =+  (x :> (head <$> yss)) :> transpose (xs :> (tail <$> yss))++-- | @'iterate' f x@ produces the infinite sequence+-- of repeated applications of @f@ to @x@.+--+-- > iterate f x = [x, f x, f (f x), ..]+iterate :: (a -> a) -> a -> Stream a+iterate f x = x :> iterate f (f x)++-- | @'cycle' xs@ returns the infinite repetition of @xs@:+--+-- > cycle [1,2,3] = Cons 1 (Cons 2 (Cons 3 (Cons 1 (Cons 2 ...+cycle :: NonEmpty a -> Stream a+cycle xs = ys where ys = foldr (:>) ys xs++-- | @'take' n xs@ returns the first @n@ elements of @xs@.+--+-- /Beware/: passing a negative integer as the first argument will+-- cause an error.+take :: Int -> Stream a -> [a]+take n ~(x :> xs)+  | n == 0 = []+  | n > 0 = x : take (n - 1) xs+  | otherwise = error "Stream.take: negative argument"++-- | @'drop' n xs@ drops the first @n@ elements off the front of+-- the sequence @xs@.+--+-- /Beware/: passing a negative integer as the first argument will+-- cause an error.+drop :: Int -> Stream a -> Stream a+drop n xs+  | n == 0 = xs+  | n > 0 = drop (n - 1) (tail xs)+  | otherwise = error "Stream.drop: negative argument"++-- | @'splitAt' n xs@ returns a pair consisting of the prefix of +-- @xs@ of length @n@ and the remaining stream immediately following +-- this prefix.+--+-- /Beware/: passing a negative integer as the first argument will+-- cause an error.+splitAt :: Int -> Stream a -> ([a],Stream a)+splitAt n xs+  | n == 0 = ([],xs)+  | n > 0, (prefix, rest) <- splitAt (n - 1) (tail xs) = (head xs : prefix, rest)+  | otherwise = error "Stream.splitAt: negative argument"++-- | @'takeWhile' p xs@ returns the longest prefix of the stream+-- @xs@ for which the predicate @p@ holds.+takeWhile :: (a -> Bool) -> Stream a -> [a]+takeWhile p (x :> xs) +  | p x = x : takeWhile p xs+  | otherwise = []++-- | @'dropWhile' p xs@ returns the suffix remaining after+-- @'takeWhile' p xs@.+--+-- /Beware/: this function may diverge if every element of @xs@+-- satisfies @p@, e.g.  @dropWhile even (repeat 0)@ will loop.+dropWhile :: (a -> Bool) -> Stream a -> Stream a+dropWhile p ~(x :> xs)+  | p x = dropWhile p xs+  | otherwise = x :> xs++-- | @'span' p xs@ returns the longest prefix of @xs@ that satisfies+-- @p@, together with the remainder of the stream.+span :: (a -> Bool) -> Stream a -> ([a], Stream a)+span p xxs@(x :> xs)+  | p x, (ts, fs) <- span p xs = (x : ts, fs)+  | otherwise = ([], xxs)++-- | The 'break' @p@ function is equivalent to 'span' @not . p@.+break :: (a -> Bool) -> Stream a -> ([a], Stream a)+break p = span (not . p)++-- | @'filter' p xs@, removes any elements from @xs@ that do not satisfy @p@.+--+-- /Beware/: this function may diverge if there is no element of+-- @xs@ that satisfies @p@, e.g.  @filter odd (repeat 0)@ will loop.+filter :: (a -> Bool) -> Stream a -> Stream a+filter p ~(x :> xs) +  | p x       = x :> filter p xs+  | otherwise = filter p xs++-- | The 'partition' function takes a predicate @p@ and a stream+-- @xs@, and returns a pair of streams. The first stream corresponds+-- to the elements of @xs@ for which @p@ holds; the second stream+-- corresponds to the elements of @xs@ for which @p@ does not hold.+--+-- /Beware/: One of the elements of the tuple may be undefined. For+-- example, @fst (partition even (repeat 0)) == repeat 0@; on the+-- other hand @snd (partition even (repeat 0))@ is undefined.+partition :: (a -> Bool) -> Stream a -> (Stream a, Stream a)+partition p ~(x :> xs)+  | p x = (x :> ts, fs)+  | otherwise = (ts, x :> fs)+  where (ts, fs) = partition p xs++-- | The 'group' function takes a stream and returns a stream of+-- lists such that flattening the resulting stream is equal to the+-- argument.  Moreover, each sublist in the resulting stream+-- contains only equal elements.  For example,+--+-- > group $ cycle "Mississippi" = "M" ::: "i" ::: "ss" ::: "i" ::: "ss" ::: "i" ::: "pp" ::: "i" ::: "M" ::: "i" ::: ...+group :: Eq a => Stream a -> Stream (NonEmpty a)+group = groupBy (==)++groupBy :: (a -> a -> Bool) -> Stream a -> Stream (NonEmpty a)+groupBy eq ~(x :> ys) +  | (xs, zs) <- span (eq x) ys +  = (x :| xs) :> groupBy eq zs++-- | The 'isPrefix' function returns @True@ if the first argument is+-- a prefix of the second.+isPrefixOf :: Eq a => [a] -> Stream a -> Bool+isPrefixOf [] _ = True+isPrefixOf (y:ys) (x :> xs)+  | y == x    = isPrefixOf ys xs+  | otherwise = False++-- | @xs !! n@ returns the element of the stream @xs@ at index+-- @n@. Note that the head of the stream has index 0.+--+-- /Beware/: passing a negative integer as the first argument will cause+-- an error.+(!!) :: Stream a -> Int -> a+(!!) (x :> xs) n+  | n == 0    = x+  | n > 0     = xs !! (n - 1)+  | otherwise = error "Stream.!! negative argument"++-- | The 'elemIndex' function returns the index of the first element+-- in the given stream which is equal (by '==') to the query element,+--+-- /Beware/: @'elemIndex' x xs@ will diverge if none of the elements+-- of @xs@ equal @x@.+elemIndex :: Eq a => a -> Stream a -> Int+elemIndex x = findIndex (\y -> x == y)++-- | The 'elemIndices' function extends 'elemIndex', by returning the+-- indices of all elements equal to the query element, in ascending order.+--+-- /Beware/: 'elemIndices' @x@ @xs@ will diverge if any suffix of+-- @xs@ does not contain @x@.+elemIndices :: Eq a => a -> Stream a -> Stream Int+elemIndices x = findIndices (x==)++-- | The 'findIndex' function takes a predicate and a stream and returns+-- the index of the first element in the stream that satisfies the predicate,+--+-- /Beware/: 'findIndex' @p@ @xs@ will diverge if none of the elements of+-- @xs@ satisfy @p@.+findIndex :: (a -> Bool) -> Stream a -> Int+findIndex p = indexFrom 0+    where+    indexFrom ix (x :> xs) +      | p x       = ix+      | otherwise = (indexFrom $! (ix + 1)) xs++-- | The 'findIndices' function extends 'findIndex', by returning the+-- indices of all elements satisfying the predicate, in ascending+-- order.+--+-- /Beware/: 'findIndices' @p@ @xs@ will diverge if all the elements+-- of any suffix of @xs@ fails to satisfy @p@.+findIndices :: (a -> Bool) -> Stream a -> Stream Int+findIndices p = indicesFrom 0 where+  indicesFrom ix (x :> xs) +    | p x = ix :> ixs +    | otherwise = ixs+    where ixs = (indicesFrom $! (ix+1)) xs++-- | The 'zip' function takes two streams and returns a list of+-- corresponding pairs.+zip :: Stream a -> Stream b -> Stream (a,b)+zip ~(x :> xs) ~(y :> ys) = (x,y) :> zip xs ys++-- | The 'zipWith' function generalizes 'zip'. Rather than tupling+-- the functions, the elements are combined using the function+-- passed as the first argument to 'zipWith'.+zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c+zipWith f ~(x :> xs) ~(y :> ys) = f x y :> zipWith f xs ys++-- | The 'unzip' function is the inverse of the 'zip' function.+unzip :: Stream (a,b) -> (Stream a, Stream b)+unzip xs = (fst <$> xs, snd <$> xs)++-- | The 'words' function breaks a stream of characters into a+-- stream of words, which were delimited by white space.+--+-- /Beware/: if the stream of characters @xs@ does not contain white+-- space, accessing the tail of @words xs@ will loop.+words :: Stream Char -> Stream String+words xs | (w, ys) <- break isSpace xs = w :> words ys++-- | The 'unwords' function is an inverse operation to 'words'. It+-- joins words with separating spaces.+unwords :: Stream String -> Stream Char+unwords ~(x :> xs) = foldr (:>) (' ' :> unwords xs) x++-- | The 'lines' function breaks a stream of characters into a list+-- of strings at newline characters. The resulting strings do not+-- contain newlines.+--+-- /Beware/: if the stream of characters @xs@ does not contain+-- newline characters, accessing the tail of @lines xs@ will loop.+lines :: Stream Char -> Stream String+lines xs | (l, ys) <- break (== '\n') xs = l :> lines (tail ys)++-- | The 'unlines' function is an inverse operation to 'lines'. It+-- joins lines, after appending a terminating newline to each.+unlines :: Stream String -> Stream Char+unlines ~(x :> xs) = foldr (:>) ('\n' :> unlines xs) x++-- | The 'fromList' converts an infinite list to a+-- stream.+--+-- /Beware/: Passing a finite list, will cause an error.+fromList :: [a] -> Stream a+fromList (x:xs) = x :> fromList xs+fromList []     = error "Stream.listToStream applied to finite list"
+ src/Data/Stream/Infinite/Functional/Zipper.hs view
@@ -0,0 +1,334 @@+{-# LANGUAGE CPP, PatternGuards, BangPatterns #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Zipper.Infinite.Functional.Zipper+-- Copyright   :  (C) 2011 Edward Kmett,+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- This is an infinite bidirectional zipper+----------------------------------------------------------------------------+module Data.Stream.Infinite.Functional.Zipper (+   -- * The type of streams+     Zipper(..)+   , tail   -- :: Zipper a -> Zipper a+   , untail -- :: Zipper a -> Zipper a +   , intersperse -- :: a -> Zipper a -> Zipper a+   , interleave  -- :: Zipper a -> Zipper a -> Zipper a+   , transpose   -- :: Zipper (Zipper a) -> Zipper (Zipper a)+   , take        -- :: Integer -> Zipper a -> [a]+   , drop        -- :: Integer -> Zipper a -> Zipper a -- you can drop a negative number+   , splitAt     -- :: Integer -> Zipper a -> ([a],Zipper a)+   , reverse     -- :: Zipper a -> Zipper a+   , (!!)        -- :: Int -> Zipper a -> a+   , unzip       -- :: Functor f => f (a, b) -> (f a, f b)+   , toSequence  -- :: (Integer -> a) -> Zipper a+   , head+   , (<|)+   , uncons+   , takeWhile+   , dropWhile+   , span+   , break+   , isPrefixOf+   , findIndex+   , elemIndex+   , zip+   , zipWith+   ) where++import Prelude hiding +  ( head, tail, map, scanr, scanr1, scanl, scanl1+  , iterate, take, drop, takeWhile+  , dropWhile, repeat, cycle, filter+  , (!!), zip, unzip, zipWith, words+  , unwords, lines, unlines, break, span+  , splitAt, foldr+  )++import Control.Applicative+import Control.Comonad+-- import Data.Char (isSpace)+#ifdef LANGUAGE_DeriveDataTypeable+import Data.Data+#endif+import Data.Functor.Extend+import Data.Functor.Apply+-- import Data.Monoid+import Data.Semigroup+-- import Data.Foldable+-- import Data.Traversable+-- import Data.Semigroup.Traversable+-- import Data.Semigroup.Foldable+-- import Data.Zipper.NonEmpty (NonEmpty(..))++data Zipper a = !Integer :~ !(Integer -> a)+#ifdef LANGUAGE_DeriveDataTypeable+  deriving Typeable+#endif++toSequence :: (Integer -> a) -> Zipper a+toSequence = (0 :~) ++infixr 0 :~++instance Functor Zipper where+  fmap g (n :~ f) = n :~ g . f+  b <$ _ = 0 :~ const b++-- | Extract the focused element+head :: Zipper a -> a+head (n :~ f) = f n++-- | Move the head of the zipper to the right+tail :: Zipper a -> Zipper a+tail (n :~ f) = n + 1 :~ f++-- | Move the head of the zipper to the left+untail :: Zipper a -> Zipper a+untail (n :~ f) = n - 1 :~ f++-- | Cons before the head of the zipper. The head now points to the new element+(<|) :: a -> Zipper a -> Zipper a+a <| (n :~ f) = n :~ \z -> case compare z n of+  LT -> f n+  EQ -> a+  GT -> f (n - 1)++-- | Move the head of the zipper one step to the right, returning the value we move over.+uncons :: Zipper a -> (a, Zipper a)+uncons (n :~ f) = (f n, n + 1 :~ f)++instance Extend Zipper where+  duplicated (n :~ f) = n :~ (:~ f)++instance Comonad Zipper where+  duplicate (n :~ f) = n :~ (:~ f)+  extract (n :~ f) = f n++instance Apply Zipper where+  (nf :~ f) <.> (na :~ a) +    | dn <- na - nf+    = nf :~ \n -> f n (a (n + dn))+  as        <.  _         = as+  _          .> bs        = bs++instance ComonadApply Zipper where+  (<@>) = (<.>)+  (<@) = (<.)+  (@>) = (.>)+++instance Applicative Zipper where+  pure = repeat+  (<*>) = (<.>)+  as <* _ = as+  _ *> bs = bs++instance Monad Zipper where+  return = repeat+  (z :~ ma) >>= f = z :~ \ na -> case f (ma na) of+    nb :~ mb -> mb (nb + na - z)++repeat :: a -> Zipper a+repeat a = 0 :~ const a++-- | Interleave two Zippers @xs@ and @ys@, alternating elements+-- from each list.+--+-- > [x1,x2,...] `interleave` [y1,y2,...] == [x1,y1,x2,y2,...]+-- > interleave = (<>) +interleave :: Zipper a -> Zipper a -> Zipper a+interleave = (<>) +instance Semigroup (Zipper a) where+  (n :~ a) <> (m :~ b) = 0 :~ \p -> case quotRem p 2 of +    (q, 0) -> a (n + q)+    (q, _) -> b (m + q)++-- | @'intersperse' y xs@ creates an alternating stream of+-- elements from @xs@ and @y@.+intersperse :: a -> Zipper a -> Zipper a+intersperse y z = z <> repeat y++-- | 'transpose' computes the transposition of a stream of streams.+transpose :: Zipper (Zipper a) -> Zipper (Zipper a)+transpose (n :~ f) = 0 :~ \z -> n :~ \n' -> let m :~ g = f n' in g (m + z)++take :: Integer -> Zipper a -> [a]+take n0 (m0 :~ f0)+  | n0 < 0 = error "Zipper.take: negative argument"+  | otherwise = go n0 m0 f0+  where+    go 0 !_ !_ = []+    go n  m  f = f m : go (n - 1) (m + 1) f+  +-- | @'drop' n xs@ drops the first @n@ elements off the front of+-- the sequence @xs@.+drop :: Integer -> Zipper a -> Zipper a+drop m (n :~ f) = m + n :~ f++-- | @'splitAt' n xs@ returns a pair consisting of the prefix of +-- @xs@ of length @n@ and the remaining stream immediately following +-- this prefix.+--+-- /Beware/: passing a negative integer as the first argument will+-- cause an error if you access the taken portion+splitAt :: Integer -> Zipper a -> ([a],Zipper a)+splitAt n xs = (take n xs, drop n xs)++-- | @'takeWhile' p xs@ returns the longest prefix of the stream+-- @xs@ for which the predicate @p@ holds.+takeWhile :: (a -> Bool) -> Zipper a -> [a]+takeWhile p0 (n0 :~ f0) = go p0 n0 f0 where +  go !p !n !f +    | x <- f n, p x = x : go p (n + 1) f+    | otherwise = []++-- | @'dropWhile' p xs@ returns the suffix remaining after+-- @'takeWhile' p xs@.+--+-- /Beware/: this function may diverge if every element of @xs@+-- satisfies @p@, e.g.  @dropWhile even (repeat 0)@ will loop.+dropWhile :: (a -> Bool) -> Zipper a -> Zipper a+dropWhile p xs@(_ :~ f) = findIndex' p xs :~ f++-- | @'span' p xs@ returns the longest prefix of @xs@ that satisfies+-- @p@, together with the remainder of the stream.+span :: (a -> Bool) -> Zipper a -> ([a], Zipper a)+span p0 (n0 :~ f0) +  | (ts, n') <- go p0 n0 f0 = (ts, n' :~ f0) where+  go !p !n !f+    | x <- f n, p x, (ts, fs) <- go p (n + 1) f = (x:ts, fs)+    | otherwise = ([], n)++-- | The 'break' @p@ function is equivalent to 'span' @not . p@.+break :: (a -> Bool) -> Zipper a -> ([a], Zipper a)+break p = span (not . p)++-- | The 'isPrefix' function returns @True@ if the first argument is+-- a prefix of the second.+isPrefixOf :: Eq a => [a] -> Zipper a -> Bool+isPrefixOf xs0 (n0 :~ f0) = go xs0 n0 f0 where+  go [] !_ !_ = True+  go (y:ys) n f = y == f n && go ys (n + 1) f++-- | @xs !! n@ returns the element of the stream @xs@ at index+-- @n@. Note that the head of the stream has index 0.+--+-- /Beware/: passing a negative integer as the first argument will cause+-- an error.+(!!) :: Zipper a -> Integer -> a+(!!) (n :~ f) m = f (n + m)++-- | The 'findIndex' function takes a predicate and a stream and returns+-- the index of the first element in the stream that satisfies the predicate,+--+-- /Beware/: 'findIndex' @p@ @xs@ will diverge if none of the elements of+-- @xs@ satisfy @p@.+findIndex :: (a -> Bool) -> Zipper a -> Integer+findIndex p0 (n0 :~ f0) = go p0 n0 f0 - n0 where+  go !p !n !f +    | x <- f n, p x = n+    | otherwise = go p (n + 1) f++-- | Internal helper, used to find an index in the +findIndex' :: (a -> Bool) -> Zipper a -> Integer+findIndex' p0 (n0 :~ f0) = go p0 n0 f0 where+  go !p !n !f +    | x <- f n, p x = n+    | otherwise = go p (n + 1) f++-- | The 'elemIndex' function returns the index of the first element+-- in the given stream which is equal (by '==') to the query element,+--+-- /Beware/: @'elemIndex' x xs@ will diverge if none of the elements+-- of @xs@ equal @x@.+elemIndex :: Eq a => a -> Zipper a -> Integer+elemIndex = findIndex . (==)++{-+-- | The 'elemIndices' function extends 'elemIndex', by returning the+-- indices of all elements equal to the query element, in ascending order.+--+-- /Beware/: 'elemIndices' @x@ @xs@ will diverge if any suffix of+-- @xs@ does not contain @x@.+elemIndices :: Eq a => a -> Zipper a -> Zipper Int+elemIndices x = findIndices (x==)+-}++-- | The 'zip' function takes two streams and returns a list of+-- corresponding pairs.+--+-- > zip = liftA2 (,)+zip :: Zipper a -> Zipper b -> Zipper (a,b)+zip = liftA2 (,)++-- | The 'zipWith' function generalizes 'zip'. Rather than tupling+-- the functions, the elements are combined using the function+-- passed as the first argument to 'zipWith'.+--+-- > zipWith = liftA2+zipWith :: (a -> b -> c) -> Zipper a -> Zipper b -> Zipper c+zipWith = liftA2++-- | The 'unzip' function is the inverse of the 'zip' function.+unzip :: Zipper (a,b) -> (Zipper a, Zipper b)+unzip xs = (fst <$> xs, snd <$> xs)++++{-++-- | The 'findIndices' function extends 'findIndex', by returning the+-- indices of all elements satisfying the predicate, in ascending+-- order.+--+-- /Beware/: 'findIndices' @p@ @xs@ will diverge if all the elements+-- of any suffix of @xs@ fails to satisfy @p@.+findIndices :: (a -> Bool) -> Zipper a -> Zipper Int+findIndices p = indicesFrom 0 where+  indicesFrom ix (x :< xs) +    | p x = ix :< ixs +    | otherwise = ixs+    where ixs = (indicesFrom $! (ix+1)) xs+++-- | The 'words' function breaks a stream of characters into a+-- stream of words, which were delimited by white space.+--+-- /Beware/: if the stream of characters @xs@ does not contain white+-- space, accessing the tail of @words xs@ will loop.+words :: Zipper Char -> Zipper String+words xs | (w, ys) <- break isSpace xs = w :< words ys++-- | The 'unwords' function is an inverse operation to 'words'. It+-- joins words with separating spaces.+unwords :: Zipper String -> Zipper Char+unwords ~(x :< xs) = foldr (:<) (' ' :< unwords xs) x++-- | The 'lines' function breaks a stream of characters into a list+-- of strings at newline characters. The resulting strings do not+-- contain newlines.+--+-- /Beware/: if the stream of characters @xs@ does not contain+-- newline characters, accessing the tail of @lines xs@ will loop.+lines :: Zipper Char -> Zipper String+lines xs | (l, ys) <- break (== '\n') xs = l :< lines (tail ys)++-- | The 'unlines' function is an inverse operation to 'lines'. It+-- joins lines, after appending a terminating newline to each.+unlines :: Zipper String -> Zipper Char+unlines ~(x :< xs) = foldr (:<) ('\n' :< unlines xs) x++-- | The 'fromList' converts an infinite list to a+-- stream.+--+-- /Beware/: Passing a finite list, will cause an error.+fromList :: [a] -> Zipper a+fromList (x:xs) = x :< fromList xs+fromList []     = error "Zipper.listToZipper applied to finite list"++-}
+ src/Data/Stream/Infinite/Skew.hs view
@@ -0,0 +1,348 @@+{-# LANGUAGE PatternGuards, BangPatterns #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Stream.Infinite.Skew+-- Copyright   :  (C) 2011 Edward Kmett,+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Anticausal streams implemented as non-empty skew binary random access lists+-- +-- The Applicative zips streams, the monad diagonalizes+------------------------------------------------------------------------------+++module Data.Stream.Infinite.Skew +    ( Stream+    , (<|)      -- O(1)+    , (!!)+    , head      -- O(1)+    , tail      -- O(1)+    , tails+    , uncons    -- O(1)+    , index     -- O(log n)+    , drop      -- O(log n)+    , dropWhile -- O(n)+    , span+    , break+    , split+    , splitW+    , repeat   +    , insert    -- O(n)+    , insertBy+    , adjust    -- O(log n)+    , update    -- O(log n)+    , fromList+    , from+    , indexed+    , interleave+    , tabulate+    ) where ++import Control.Arrow (first)+import Control.Applicative hiding (empty)+import Control.Comonad+import Data.Distributive+import Data.Functor.Alt+import Data.Functor.Extend+import Data.Foldable hiding (toList)+import Data.Traversable+import Data.Semigroup hiding (Last)+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Prelude hiding (null, head, tail, drop, dropWhile, length, foldr, last, span, repeat, replicate, (!!), break)++infixr 5 :<, <|++data Complete a +    = Tip a+    | Bin !Integer a !(Complete a) !(Complete a)+    deriving Show++instance Functor Complete where+  fmap f (Tip a) = Tip (f a)+  fmap f (Bin w a l r) = Bin w (f a) (fmap f l) (fmap f r)++instance Extend Complete where+  extended f w@Tip {} = Tip (f w)+  extended f w@(Bin n _ l r) = Bin n (f w) (extended f l) (extended f r)++instance Comonad Complete where+  extend f w@Tip {} = Tip (f w)+  extend f w@(Bin n _ l r) = Bin n (f w) (extend f l) (extend f r)+  extract (Tip a) = a+  extract (Bin _ a _ _) = a++instance Foldable Complete where+  foldMap f (Tip a) = f a +  foldMap f (Bin _ a l r) = f a `mappend` foldMap f l `mappend` foldMap f r+  foldr f z (Tip a) = f a z+  foldr f z (Bin _ a l r) = f a (foldr f (foldr f z r) l)++instance Foldable1 Complete where+  foldMap1 f (Tip a) = f a+  foldMap1 f (Bin _ a l r) = f a <> foldMap1 f l <> foldMap1 f r++instance Traversable Complete where+  traverse f (Tip a) = Tip <$> f a +  traverse f (Bin n a l r) = Bin n <$> f a <*> traverse f l <*> traverse f r++instance Traversable1 Complete where+  traverse1 f (Tip a) = Tip <$> f a +  traverse1 f (Bin n a l r) = Bin n <$> f a <.> traverse1 f l <.> traverse1 f r++bin :: a -> Complete a -> Complete a -> Complete a +bin a l r = Bin (1 + weight l + weight r) a l r+{-# INLINE bin #-}++weight :: Complete a -> Integer+weight Tip{} = 1+weight (Bin w _ _ _) = w+{-# INLINE weight #-}++-- A future is a non-empty skew binary random access list of nodes.+-- The last node, however, is allowed to contain fewer values. +data Stream a = !(Complete a) :< Stream a+--  deriving Show++instance Show a => Show (Stream a) where+  showsPrec d as = showParen (d >= 10) $ +    showString "fromList " . showsPrec 11 (toList as)++instance Functor Stream where+  fmap f (t :< ts) = fmap f t :< fmap f ts++instance Extend Stream where+  extended = extend++instance Comonad Stream where+  extend g0 (t :< ts) = go g0 t (:< ts) :< extend g0 ts+    where+      go :: (Stream a -> b) -> Complete a -> (Complete a -> Stream a) -> Complete b+      go g w@Tip{}         f = Tip (g (f w))+      go g w@(Bin n _ l r) f = Bin n (g (f w)) (go g l (:< f r))  (go g r f)+  extract = head++instance Apply Stream where+  fs <.> as = mapWithIndex (\n f -> f (as !! n)) fs+  as <.  _  = as+  _   .> bs = bs++instance ComonadApply Stream where+  (<@>) = (<.>)+  (<@) = (<.)+  (@>) = (.>)++instance Applicative Stream where+  pure = repeat+  (<*>) = (<.>)+  (<* ) = (<. )+  ( *>) = ( .>)++instance Alt Stream where+  as <!> bs = tabulate $ \i -> case quotRem i 2 of +    (q,0) -> as !! q+    (q,_) -> bs !! q+++instance Foldable Stream where+  foldMap f (t :< ts) = foldMap f t `mappend` foldMap f ts+  foldr f z (t :< ts) = foldr f (foldr f z ts) t++toList :: Stream a -> [a]+toList = foldr (:) []++instance Foldable1 Stream where+  foldMap1 f (t :< ts) = foldMap1 f t <> foldMap1 f ts++instance Traversable Stream where+  traverse f (t :< ts) = (:<) <$> traverse f t <*> traverse f ts++instance Traversable1 Stream where+  traverse1 f (t :< ts) = (:<) <$> traverse1 f t <.> traverse1 f ts++instance Distributive Stream where+  distribute w = tabulate (\i -> fmap (!! i) w)++instance Semigroup (Stream a) where+  (<>) = (<!>)++instance Monad Stream where+  return = pure+  as >>= f = mapWithIndex (\i a -> f a !! i) as++interleave :: Stream a -> Stream a -> Stream a+interleave = (<!>) +      +repeat :: a -> Stream a +repeat b = go b (Tip b) +    where +      go :: a -> Complete a -> Stream a +      go a as | ass <- bin a as as = as :< go a ass++mapWithIndex :: (Integer -> a -> b) -> Stream a -> Stream b+mapWithIndex f0 as0 = spine f0 0 as0+  where +    spine f m (a :< as) = tree f m a :< spine f (m + weight a) as+    tree f m (Tip a) = Tip (f m a)+    tree f m (Bin n a l r) = Bin n (f m a) (tree f (m + 1) l) (tree f (m + 1 + weight l) r)++tabulate :: (Integer -> a) -> Stream a+tabulate f = mapWithIndex (const . f) (pure ())+++indexed :: Stream a -> Stream (Integer, a)+indexed = mapWithIndex (,)++from :: Num a => a -> Stream a+from a = mapWithIndex ((+) . fromIntegral) (pure a)++-- | /O(1)/ cons+(<|) :: a -> Stream a -> Stream a+a <| (l :< r :< as) +  | weight l == weight r = bin a l r :< as+a <| as = Tip a :< as+{-# INLINE (<|) #-}++-- | /O(1)/+head :: Stream a -> a+head (a :< _) = extract a+{-# INLINE head #-}++-- | /O(1)/.+tail :: Stream a -> Stream a+tail (Tip{} :< ts) = ts+tail (Bin _ _ l r :< ts) = l :< r :< ts+{-# INLINE tail #-}++tails :: Stream a -> Stream (Stream a)+tails = duplicate+{-# INLINE tails #-}++-- | /O(1)/.+uncons :: Stream a -> (a, Stream a)+uncons (Tip a       :< as)  = (a, as)+uncons (Bin _ a l r :< as)  = (a, l :< r :< as)+{-# INLINE uncons #-}++-- | /O(log n)/.+index :: Integer -> Stream a -> a+index i (t :< ts) +  | i < 0     = error "index: negative index"+  | i < w     = indexComplete i t+  | otherwise = index (i - w) ts+  where w = weight t++indexComplete :: Integer -> Complete a -> a+indexComplete 0 (Tip a) = a+indexComplete 0 (Bin _ a _ _) = a+indexComplete i (Bin w _ l r) +  | i <= w'   = indexComplete (i-1) l+  | otherwise = indexComplete (i-1-w') r+  where w' = div w 2+indexComplete _ _ = error "indexComplete"++-- | /O(log n)/.+(!!) :: Stream a -> Integer -> a+(!!) = flip index ++-- | /O(log n)/.+drop :: Integer -> Stream a -> Stream a+drop 0 ts = ts+drop i (t :< ts) = case compare i w of+  LT -> dropComplete i t (:< ts)+  EQ -> ts+  GT -> drop (i - w) ts+  where w = weight t++dropComplete :: Integer -> Complete a -> (Complete a -> Stream a) -> Stream a +dropComplete 0 t f             = f t+dropComplete 1 (Bin _ _ l r) f = l :< f r+dropComplete i (Bin w _ l r) f = case compare (i - 1) w' of+    LT -> dropComplete (i-1) l (:< f r)+    EQ -> f r+    GT -> dropComplete (i-1-w') r f+    where w' = div w 2+dropComplete _ _ _ = error "dropComplete"++-- /O(n)/.+dropWhile :: (a -> Bool) -> Stream a -> Stream a+dropWhile p as +  | p (head as) = dropWhile p (tail as)+  | otherwise   = as++-- /O(n)/+span :: (a -> Bool) -> Stream a -> ([a], Stream a)+span p as+  | a <- head as, p a = first (a:) $ span p (tail as)+  | otherwise = ([], as)++-- /O(n)/+break :: (a -> Bool) -> Stream a -> ([a], Stream a)+break p = span (not . p)++-- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.+-- best used with a monotonic function+split :: (a -> Bool) -> Stream a -> ([a], Stream a)+split p (a :< as)+  | p (extract as) = splitComplete p a (:< as)+  | (ts, fs) <- split p as = (foldr (:) ts a, fs)++-- for use when we know the split occurs within a given tree+splitComplete :: (a -> Bool) -> Complete a -> (Complete a -> Stream a) -> ([a], Stream a)+splitComplete _ t@Tip{} f = ([], f t)+splitComplete p t@(Bin _ a l r) f+  | p a                                                   = ([], f t)+  | p (extract r), (ts, fs) <- splitComplete p l (:< f r) = (a:ts, fs)+  |                (ts, fs) <- splitComplete p r f        = (a:foldr (:) ts l, fs)++-- /(O(n), O(log n))/ split at _some_ edge where function goes from False to True.+-- best used with a monotonic function+--+-- > splitW p xs = (map extract &&& fmap (fmap extract)) . split p . duplicate+splitW :: (Stream a -> Bool) -> Stream a -> ([a], Stream a)+splitW p (a :< as) +  | p as                    = splitCompleteW p a (:< as)+  | (ts, fs) <- splitW p as = (foldr (:) ts a, fs)++-- for use when we know the split occurs within a given tree+splitCompleteW :: (Stream a -> Bool) -> Complete a -> (Complete a -> Stream a) -> ([a], Stream a)+splitCompleteW _ t@Tip{} f = ([], f t)+splitCompleteW p t@(Bin _ a l r) f+  | w <- f t, p w                                        = ([], w)+  | w <- f r, p w, (ts, fs) <- splitCompleteW p l (:< w) = (a:ts, fs)+  |                (ts, fs) <- splitCompleteW p r f      = (a:foldr (:) ts l, fs)++fromList :: [a] -> Stream a+fromList = foldr (<|) (error "fromList: finite list")++-- /O(n)/+insert :: Ord a => a -> Stream a -> Stream a+insert a as | (ts, as') <- split (a<=) as = foldr (<|) (a <| as') ts++-- /O(n)/. Finds the split in O(log n), but then has to recons+insertBy :: (a -> a -> Ordering) -> a -> Stream a -> Stream a+insertBy cmp a as | (ts, as') <- split (\b -> cmp a b <= EQ) as = foldr (<|) (a <| as') ts++-- /O(log n)/ Change the value of the nth entry in the future+adjust :: Integer -> (a -> a) -> Stream a -> Stream a+adjust !n f (a :< as) +  | n < w = adjustComplete n f a :< as+  | otherwise = a :< adjust (n - w) f as+  where w = weight a++adjustComplete :: Integer -> (a -> a) -> Complete a -> Complete a+adjustComplete 0 f (Tip a) = Tip (f a)+adjustComplete _ _ t@Tip{} = t+adjustComplete n f (Bin m a l r) +  | n == 0 = Bin m (f a) l r+  | n < w = Bin m a (adjustComplete (n - 1) f l) r+  | otherwise = Bin m a l (adjustComplete (n - 1 - w) f r)+  where w = weight l++update :: Integer -> a -> Stream a -> Stream a+update n = adjust n . const+
+ src/Data/Stream/Supply.hs view
@@ -0,0 +1,174 @@+{-# LANGUAGE CPP, FlexibleContexts #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Stream.Supply+-- Copyright   :  (C) 2008-2011 Edward Kmett,+--                (C) 2008 Iavor S. Diatchki+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- This library can be used to generate values (for example, new names)+-- without the need to thread state.  This means that functions that+-- need to generate new values only need a supply object as an argument,+-- and they do not need to return a new supply object as a result.+-- This decreases the number of data-dependencies in a program, which+-- makes it easier to exploit parallelism.+--+-- The technique for generating new values is based on the paper+-- ''On Generating Unique Names'' by Lennart Augustsson, Mikael Rittri, +-- and Dan Synek.+----------------------------------------------------------------------------+module Data.Stream.Supply+  ( Supply+  , newSupply+  , newEnumSupply+  , newNumSupply+  , newDupableSupply+  , newDupableEnumSupply+  , newDupableNumSupply+  , leftSupply+  , rightSupply+  , split+  , splits+  , splitSkew+  , split2+  , split3+  , split4+  ) where++import Control.Applicative+import Control.Comonad+import Data.Functor.Apply+import Data.Functor.Extend+import Data.Foldable+import Data.IORef(newIORef, atomicModifyIORef)+import Data.Traversable+import Data.Semigroup+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import System.IO.Unsafe (unsafeInterleaveIO)+import Data.Stream.Infinite+import qualified Data.Stream.Infinite.Skew as Skew++#ifdef LANGUAGE_DeriveDataTypeable+import Data.Data+#endif++#ifdef __GLASGOW_HASKELL__ >= 608 +import GHC.IO(unsafeDupableInterleaveIO)+#else+unsafeDupableInterleaveIO :: IO a -> IO a+unsafeDupableInterleaveIO = unsafeInterleaveIO+#endif++data Supply a = Supply a (Supply a) (Supply a) deriving +  ( Show, Read, Eq, Ord+#ifdef LANGUAGE_DeriveDataTypeable+  , Data, Typeable+#endif+  )++instance Functor Supply where+  fmap f (Supply a l r) = Supply (f a) (fmap f l) (fmap f r)+  a <$ _ = pure a++instance Extend Supply where+  extended f s@(Supply _ l r) = Supply (f s) (extended f l) (extended f r)+  duplicated s@(Supply _ l r) = Supply s (duplicated l) (duplicated r)++instance Comonad Supply where+  extend f s@(Supply _ l r) = Supply (f s) (extend f l) (extend f r)+  duplicate s@(Supply _ l r) = Supply s (duplicate l) (duplicate r)+  extract (Supply a _ _) = a++instance Apply Supply where+  Supply f fl fr <.> Supply a al ar = Supply (f a) (fl <.> al) (fr <.> ar)+  a <. _ = a+  _ .> a = a++instance Applicative Supply where+  pure a = as where as = Supply a as as+  Supply f fl fr <*> Supply a al ar = Supply (f a) (fl <*> al) (fr <*> ar)+  a <* _ = a+  _ *> a = a++instance Foldable Supply where+  foldMap f (Supply a l r) = f a `mappend` foldMap f l `mappend` foldMap f r++instance Foldable1 Supply where+  foldMap1 f (Supply a l r) = f a <> foldMap1 f l <> foldMap1 f r++instance Traversable Supply where+  traverse f (Supply a l r) = Supply <$> f a <*> traverse f l <*> traverse f r++instance Traversable1 Supply where+  traverse1 f (Supply a l r) = Supply <$> f a <.> traverse1 f l <.> traverse1 f r+  +leftSupply :: Supply a -> Supply a+leftSupply (Supply _ l _) = l++rightSupply :: Supply a -> Supply a+rightSupply (Supply _ _ r) = r++-- unfoldsW :: (Comonad w, Functor f) => (w a -> (b, f a)) -> w a -> StreamT f w b+newSupply :: (a -> a) -> a -> IO (Supply a)+newSupply f x = gen =<< newIORef x+  where gen r = unsafeInterleaveIO $+          Supply <$> unsafeInterleaveIO (atomicModifyIORef r update) +                 <*> gen r +                 <*> gen r+        update a = b `seq` (b, a) where b = f a+{-# INLINE newSupply #-}++newDupableSupply :: (a -> a) -> a -> IO (Supply a)+newDupableSupply f x = gen =<< newIORef x+  where gen r = unsafeDupableInterleaveIO $+          Supply <$> unsafeDupableInterleaveIO (atomicModifyIORef r update)+                 <*> gen r+                 <*> gen r+        update a = b `seq` (b, a) where b = f a+{-# INLINE newDupableSupply #-}++newEnumSupply :: Enum a => IO (Supply a)+newEnumSupply = newSupply succ (toEnum 0)+{-# SPECIALIZE newEnumSupply :: IO (Supply Int) #-}++newNumSupply :: Num a => IO (Supply a)+newNumSupply = newSupply (1+) 0+{-# SPECIALIZE newNumSupply :: IO (Supply Int) #-}++newDupableEnumSupply :: Enum a => IO (Supply a)+newDupableEnumSupply = newSupply succ (toEnum 0)+{-# SPECIALIZE newEnumSupply :: IO (Supply Int) #-}++newDupableNumSupply :: Num a => IO (Supply a)+newDupableNumSupply = newSupply (1+) 0+{-# SPECIALIZE newNumSupply :: IO (Supply Int) #-}++split :: Supply a -> Stream (Supply a)+split (Supply _ l r) = l :> split r++splits :: Integral b => Supply a -> b -> Supply a+splits (Supply _ l r) n = case n `quotRem` 2 of+  (0,0)  -> leftSupply l+  (q,-1) -> splits (rightSupply l) q+  (q,0)  -> splits (leftSupply r) q+  (q,1)  -> splits (rightSupply r) q+  (_,_)  -> error "quotRem: impossible result"+{-# SPECIALIZE splits :: Supply a -> Int -> Supply a #-}+{-# SPECIALIZE splits :: Supply a -> Integer -> Supply a #-}++splitSkew :: Supply a -> Skew.Stream (Supply a)+splitSkew = Skew.tabulate . splits++split2 :: Supply a -> (Supply a, Supply a)+split2 (Supply _ l r) = (l, r)++split3 :: Supply a -> (Supply a, Supply a, Supply a)+split3 (Supply _ a (Supply _ b c)) = (a, b, c)++split4 :: Supply a -> (Supply a, Supply a, Supply a, Supply a)+split4 (Supply _ (Supply _ a b) (Supply _ c d)) = (a, b, c, d)
streams.cabal view
@@ -1,6 +1,6 @@ name:          streams category:      Control, Comonads-version:       3.0.0.1+version:       3.0.1 license:       BSD3 cabal-version: >= 1.6 license-file:  LICENSE@@ -9,7 +9,7 @@ stability:     provisional homepage:      http://github.com/ekmett/streams homepage:      http://github.com/ekmett/streams/issues-copyright:     Copyright 2011-2012 Edward Kmett+copyright:     Copyright 2011-2013 Edward Kmett                Copyright 2010 Tony Morris, Oliver Taylor, Eelis van der Weegen                Copyright 2007-2010 Wouter Swierstra, Bas van Dijk                Copyright 2008 Iavor S. Diatchki@@ -52,24 +52,6 @@   .   * "Data.Stream.Supply" provides a comonadic supply of unique values, which are     generated impurely as the tree is explored.-  .-  /Changes since 0.6.3/:-  .-  * "Data.Stream.NonEmpty" renamed to "Data.List.NonEmpty" and pushed upstream into the semigroups package.-  .-  /Changes since 0.5.1/:-  .-  * Removed a redundant UNPACK pragma-  .-  /Changes since 0.5/:-  .-  * Data.Stream.Supply added-  .-  /Changes since 0.1/:-  .-  * A number of strictness issues with 'NonEmpty' were fixed-  .-  * More documentation  source-repository head   type: git@@ -81,11 +63,11 @@     BangPatterns    build-depends:-    base          >= 4       && < 5,-    comonad       == 3.0.*,-    distributive  >= 0.2.1   && < 0.4,-    semigroupoids == 3.0.*,-    semigroups    >= 0.8.3.1 && < 0.9+    base          >= 4 && < 5,+    comonad       >= 3,+    distributive  >= 0.2.1,+    semigroupoids >= 3,+    semigroups    >= 0.8.3.1    extensions: CPP   if impl(ghc)@@ -100,5 +82,6 @@     Data.Stream.Infinite.Functional.Zipper     Data.Stream.Supply +  hs-source-dirs: src   ghc-options: -Wall