{-# LANGUAGE UndecidableInstances, CPP #-}
module ListT
(
  ListT(..),
  -- * Execution utilities
  uncons,
  head,
  tail,
  null,
  fold,
  foldMaybe,
  applyFoldM,
  toList,
  toReverseList,
  traverse_,
  splitAt,
  -- * Construction utilities
  cons,
  fromFoldable,
  fromMVar,
  unfold,
  unfoldM,
  repeat,
  -- * Transformation utilities
  -- | 
  -- These utilities only accumulate the transformations
  -- without actually traversing the stream.
  -- They only get applied in a single traversal, 
  -- which only happens at the execution.
  traverse,
  take,
  drop,
  slice,
)
where

import ListT.Prelude hiding (uncons, toList, yield, fold, traverse, head, tail, take, drop, repeat, null, traverse_, splitAt)
import Control.Monad

-- |
-- A proper implementation of the list monad-transformer.
-- Useful for streaming of monadic data structures.
-- 
-- Since it has instances of 'MonadPlus' and 'Alternative',
-- you can use general utilities packages like
-- <http://hackage.haskell.org/package/monadplus "monadplus">
-- with it.
newtype ListT m a =
  ListT (m (Maybe (a, ListT m a)))

instance Monad m => Semigroup (ListT m a) where
  <> :: ListT m a -> ListT m a -> ListT m a
(<>) (ListT m1 :: m (Maybe (a, ListT m a))
m1) (ListT m2 :: m (Maybe (a, ListT m a))
m2) =
    m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> m (Maybe (a, ListT m a)) -> ListT m a
forall a b. (a -> b) -> a -> b
$
      m (Maybe (a, ListT m a))
m1 m (Maybe (a, ListT m a))
-> (Maybe (a, ListT m a) -> m (Maybe (a, ListT m a)))
-> m (Maybe (a, ListT m a))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
        \case
          Nothing ->
            m (Maybe (a, ListT m a))
m2
          Just (h1 :: a
h1, s1' :: ListT m a
s1') ->
            Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, ListT m a) -> Maybe (a, ListT m a)
forall a. a -> Maybe a
Just (a
h1, (ListT m a -> ListT m a -> ListT m a
forall a. Semigroup a => a -> a -> a
(<>) ListT m a
s1' (m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT m (Maybe (a, ListT m a))
m2))))

instance Monad m => Monoid (ListT m a) where
  mempty :: ListT m a
mempty =
    m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> m (Maybe (a, ListT m a)) -> ListT m a
forall a b. (a -> b) -> a -> b
$ 
      Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (a, ListT m a)
forall a. Maybe a
Nothing
  mappend :: ListT m a -> ListT m a -> ListT m a
mappend = ListT m a -> ListT m a -> ListT m a
forall a. Semigroup a => a -> a -> a
(<>)

instance Functor m => Functor (ListT m) where
  fmap :: (a -> b) -> ListT m a -> ListT m b
fmap f :: a -> b
f =
    m (Maybe (b, ListT m b)) -> ListT m b
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (b, ListT m b)) -> ListT m b)
-> (ListT m a -> m (Maybe (b, ListT m b)))
-> ListT m a
-> ListT m b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Maybe (a, ListT m a) -> Maybe (b, ListT m b))
-> m (Maybe (a, ListT m a)) -> m (Maybe (b, ListT m b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Maybe (a, ListT m a) -> Maybe (b, ListT m b))
 -> m (Maybe (a, ListT m a)) -> m (Maybe (b, ListT m b)))
-> (((a, ListT m a) -> (b, ListT m b))
    -> Maybe (a, ListT m a) -> Maybe (b, ListT m b))
-> ((a, ListT m a) -> (b, ListT m b))
-> m (Maybe (a, ListT m a))
-> m (Maybe (b, ListT m b))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((a, ListT m a) -> (b, ListT m b))
-> Maybe (a, ListT m a) -> Maybe (b, ListT m b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (a -> b
f (a -> b)
-> (ListT m a -> ListT m b) -> (a, ListT m a) -> (b, ListT m b)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (a -> b) -> ListT m a -> ListT m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) (m (Maybe (a, ListT m a)) -> m (Maybe (b, ListT m b)))
-> (ListT m a -> m (Maybe (a, ListT m a)))
-> ListT m a
-> m (Maybe (b, ListT m b))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons

instance (Monad m, Functor m) => Applicative (ListT m) where
  pure :: a -> ListT m a
pure = 
    a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> m a
return
  <*> :: ListT m (a -> b) -> ListT m a -> ListT m b
(<*>) = 
    ListT m (a -> b) -> ListT m a -> ListT m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance (Monad m, Functor m) => Alternative (ListT m) where
  empty :: ListT m a
empty = 
    ListT m a -> ListT m a
forall a. a -> a
inline ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
  <|> :: ListT m a -> ListT m a -> ListT m a
(<|>) = 
    (ListT m a -> ListT m a -> ListT m a)
-> ListT m a -> ListT m a -> ListT m a
forall a. a -> a
inline ListT m a -> ListT m a -> ListT m a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus

instance Monad m => Monad (ListT m) where
  return :: a -> ListT m a
return a :: a
a =
    m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> m (Maybe (a, ListT m a)) -> ListT m a
forall a b. (a -> b) -> a -> b
$ Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, ListT m a) -> Maybe (a, ListT m a)
forall a. a -> Maybe a
Just (a
a, (m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (a, ListT m a)
forall a. Maybe a
Nothing))))
  >>= :: ListT m a -> (a -> ListT m b) -> ListT m b
(>>=) s1 :: ListT m a
s1 k2 :: a -> ListT m b
k2 =
    m (Maybe (b, ListT m b)) -> ListT m b
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (b, ListT m b)) -> ListT m b)
-> m (Maybe (b, ListT m b)) -> ListT m b
forall a b. (a -> b) -> a -> b
$
      ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons ListT m a
s1 m (Maybe (a, ListT m a))
-> (Maybe (a, ListT m a) -> m (Maybe (b, ListT m b)))
-> m (Maybe (b, ListT m b))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
        \case
          Nothing ->
            Maybe (b, ListT m b) -> m (Maybe (b, ListT m b))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (b, ListT m b)
forall a. Maybe a
Nothing
          Just (h1 :: a
h1, t1 :: ListT m a
t1) ->
            ListT m b -> m (Maybe (b, ListT m b))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons (ListT m b -> m (Maybe (b, ListT m b)))
-> ListT m b -> m (Maybe (b, ListT m b))
forall a b. (a -> b) -> a -> b
$ a -> ListT m b
k2 a
h1 ListT m b -> ListT m b -> ListT m b
forall a. Semigroup a => a -> a -> a
<> (ListT m a
t1 ListT m a -> (a -> ListT m b) -> ListT m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> ListT m b
k2)
#if !MIN_VERSION_base(4,11,0)
  fail _ =
    mempty
#endif

instance Monad m => MonadFail (ListT m) where
  fail :: String -> ListT m a
fail _ =
    ListT m a -> ListT m a
forall a. a -> a
inline ListT m a
forall a. Monoid a => a
mempty

instance Monad m => MonadPlus (ListT m) where
  mzero :: ListT m a
mzero = 
    ListT m a -> ListT m a
forall a. a -> a
inline ListT m a
forall a. Monoid a => a
mempty
  mplus :: ListT m a -> ListT m a -> ListT m a
mplus = 
    (ListT m a -> ListT m a -> ListT m a)
-> ListT m a -> ListT m a -> ListT m a
forall a. a -> a
inline ListT m a -> ListT m a -> ListT m a
forall a. Monoid a => a -> a -> a
mappend

instance MonadTrans ListT where
  lift :: m a -> ListT m a
lift =
    m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> (m a -> m (Maybe (a, ListT m a))) -> m a -> ListT m a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a -> Maybe (a, ListT m a)) -> m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\a :: a
a -> (a, ListT m a) -> Maybe (a, ListT m a)
forall a. a -> Maybe a
Just (a
a, ListT m a
forall a. Monoid a => a
mempty))

instance MonadIO m => MonadIO (ListT m) where
  liftIO :: IO a -> ListT m a
liftIO =
    m a -> ListT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ListT m a) -> (IO a -> m a) -> IO a -> ListT m a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

instance MFunctor ListT where
  hoist :: (forall a. m a -> n a) -> ListT m b -> ListT n b
hoist f :: forall a. m a -> n a
f =
    n (Maybe (b, ListT n b)) -> ListT n b
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (n (Maybe (b, ListT n b)) -> ListT n b)
-> (ListT m b -> n (Maybe (b, ListT n b)))
-> ListT m b
-> ListT n b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. m (Maybe (b, ListT n b)) -> n (Maybe (b, ListT n b))
forall a. m a -> n a
f (m (Maybe (b, ListT n b)) -> n (Maybe (b, ListT n b)))
-> (ListT m b -> m (Maybe (b, ListT n b)))
-> ListT m b
-> n (Maybe (b, ListT n b))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Maybe (b, ListT m b) -> Maybe (b, ListT n b))
-> m (Maybe (b, ListT m b)) -> m (Maybe (b, ListT n b))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((Maybe (b, ListT m b) -> Maybe (b, ListT n b))
 -> m (Maybe (b, ListT m b)) -> m (Maybe (b, ListT n b)))
-> (((b, ListT m b) -> (b, ListT n b))
    -> Maybe (b, ListT m b) -> Maybe (b, ListT n b))
-> ((b, ListT m b) -> (b, ListT n b))
-> m (Maybe (b, ListT m b))
-> m (Maybe (b, ListT n b))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((b, ListT m b) -> (b, ListT n b))
-> Maybe (b, ListT m b) -> Maybe (b, ListT n b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (b -> b
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id (b -> b)
-> (ListT m b -> ListT n b) -> (b, ListT m b) -> (b, ListT n b)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (forall a. m a -> n a) -> ListT m b -> ListT n b
forall k (t :: (* -> *) -> k -> *) (m :: * -> *) (n :: * -> *)
       (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
hoist forall a. m a -> n a
f) (m (Maybe (b, ListT m b)) -> m (Maybe (b, ListT n b)))
-> (ListT m b -> m (Maybe (b, ListT m b)))
-> ListT m b
-> m (Maybe (b, ListT n b))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m b -> m (Maybe (b, ListT m b))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons

instance MMonad ListT where
  embed :: (forall a. m a -> ListT n a) -> ListT m b -> ListT n b
embed f :: forall a. m a -> ListT n a
f (ListT m :: m (Maybe (b, ListT m b))
m) =
    m (Maybe (b, ListT m b)) -> ListT n (Maybe (b, ListT m b))
forall a. m a -> ListT n a
f m (Maybe (b, ListT m b))
m ListT n (Maybe (b, ListT m b))
-> (Maybe (b, ListT m b) -> ListT n b) -> ListT n b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Nothing -> ListT n b
forall (m :: * -> *) a. MonadPlus m => m a
mzero
      Just (h :: b
h, t :: ListT m b
t) -> n (Maybe (b, ListT n b)) -> ListT n b
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (n (Maybe (b, ListT n b)) -> ListT n b)
-> n (Maybe (b, ListT n b)) -> ListT n b
forall a b. (a -> b) -> a -> b
$ Maybe (b, ListT n b) -> n (Maybe (b, ListT n b))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (b, ListT n b) -> n (Maybe (b, ListT n b)))
-> Maybe (b, ListT n b) -> n (Maybe (b, ListT n b))
forall a b. (a -> b) -> a -> b
$ (b, ListT n b) -> Maybe (b, ListT n b)
forall a. a -> Maybe a
Just ((b, ListT n b) -> Maybe (b, ListT n b))
-> (b, ListT n b) -> Maybe (b, ListT n b)
forall a b. (a -> b) -> a -> b
$ (b
h, (forall a. m a -> ListT n a) -> ListT m b -> ListT n b
forall (t :: (* -> *) -> * -> *) (n :: * -> *) (m :: * -> *) b.
(MMonad t, Monad n) =>
(forall a. m a -> t n a) -> t m b -> t n b
embed forall a. m a -> ListT n a
f ListT m b
t)

instance MonadBase b m => MonadBase b (ListT m) where
  liftBase :: b α -> ListT m α
liftBase =
    m α -> ListT m α
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m α -> ListT m α) -> (b α -> m α) -> b α -> ListT m α
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. b α -> m α
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase

instance MonadBaseControl b m => MonadBaseControl b (ListT m) where
  type StM (ListT m) a =
    StM m (Maybe (a, ListT m a))
  liftBaseWith :: (RunInBase (ListT m) b -> b a) -> ListT m a
liftBaseWith runToBase :: RunInBase (ListT m) b -> b a
runToBase =
    m a -> ListT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ListT m a) -> m a -> ListT m a
forall a b. (a -> b) -> a -> b
$ (RunInBase m b -> b a) -> m a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b a) -> m a
liftBaseWith ((RunInBase m b -> b a) -> m a) -> (RunInBase m b -> b a) -> m a
forall a b. (a -> b) -> a -> b
$ \runInner :: RunInBase m b
runInner -> 
      RunInBase (ListT m) b -> b a
runToBase (RunInBase (ListT m) b -> b a) -> RunInBase (ListT m) b -> b a
forall a b. (a -> b) -> a -> b
$ m (Maybe (a, ListT m a)) -> b (StM m (Maybe (a, ListT m a)))
RunInBase m b
runInner (m (Maybe (a, ListT m a)) -> b (StM m (Maybe (a, ListT m a))))
-> (ListT m a -> m (Maybe (a, ListT m a)))
-> ListT m a
-> b (StM m (Maybe (a, ListT m a)))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons
  restoreM :: StM (ListT m) a -> ListT m a
restoreM inner :: StM (ListT m) a
inner =
    m (Maybe (a, ListT m a)) -> ListT m (Maybe (a, ListT m a))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StM m (Maybe (a, ListT m a)) -> m (Maybe (a, ListT m a))
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
StM m a -> m a
restoreM StM m (Maybe (a, ListT m a))
StM (ListT m) a
inner) ListT m (Maybe (a, ListT m a))
-> (Maybe (a, ListT m a) -> ListT m a) -> ListT m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Nothing -> ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
      Just (h :: a
h, t :: ListT m a
t) -> a -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons a
h ListT m a
t

instance MonadError e m => MonadError e (ListT m) where
  throwError :: e -> ListT m a
throwError = m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> (e -> m (Maybe (a, ListT m a))) -> e -> ListT m a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. e -> m (Maybe (a, ListT m a))
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
  catchError :: ListT m a -> (e -> ListT m a) -> ListT m a
catchError m :: ListT m a
m handler :: e -> ListT m a
handler = m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> m (Maybe (a, ListT m a)) -> ListT m a
forall a b. (a -> b) -> a -> b
$ m (Maybe (a, ListT m a))
-> (e -> m (Maybe (a, ListT m a))) -> m (Maybe (a, ListT m a))
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError (ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons ListT m a
m) ((e -> m (Maybe (a, ListT m a))) -> m (Maybe (a, ListT m a)))
-> (e -> m (Maybe (a, ListT m a))) -> m (Maybe (a, ListT m a))
forall a b. (a -> b) -> a -> b
$ ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons (ListT m a -> m (Maybe (a, ListT m a)))
-> (e -> ListT m a) -> e -> m (Maybe (a, ListT m a))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. e -> ListT m a
handler


-- * Execution in the inner monad
-------------------------

-- |
-- Execute in the inner monad,
-- getting the head and the tail.
-- Returns nothing if it's empty.
uncons :: ListT m a -> m (Maybe (a, ListT m a))
uncons :: ListT m a -> m (Maybe (a, ListT m a))
uncons (ListT m :: m (Maybe (a, ListT m a))
m) =
  m (Maybe (a, ListT m a))
m

-- |
-- Execute, getting the head. Returns nothing if it's empty.
{-# INLINABLE head #-}
head :: Monad m => ListT m a -> m (Maybe a)
head :: ListT m a -> m (Maybe a)
head =
  (Maybe (a, ListT m a) -> Maybe a)
-> m (Maybe (a, ListT m a)) -> m (Maybe a)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (((a, ListT m a) -> a) -> Maybe (a, ListT m a) -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, ListT m a) -> a
forall a b. (a, b) -> a
fst) (m (Maybe (a, ListT m a)) -> m (Maybe a))
-> (ListT m a -> m (Maybe (a, ListT m a)))
-> ListT m a
-> m (Maybe a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons

-- |
-- Execute, getting the tail. Returns nothing if it's empty.
{-# INLINABLE tail #-}
tail :: Monad m => ListT m a -> m (Maybe (ListT m a))
tail :: ListT m a -> m (Maybe (ListT m a))
tail =
  (Maybe (a, ListT m a) -> Maybe (ListT m a))
-> m (Maybe (a, ListT m a)) -> m (Maybe (ListT m a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (((a, ListT m a) -> ListT m a)
-> Maybe (a, ListT m a) -> Maybe (ListT m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, ListT m a) -> ListT m a
forall a b. (a, b) -> b
snd) (m (Maybe (a, ListT m a)) -> m (Maybe (ListT m a)))
-> (ListT m a -> m (Maybe (a, ListT m a)))
-> ListT m a
-> m (Maybe (ListT m a))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons

-- |
-- Execute, checking whether it's empty.
{-# INLINABLE null #-}
null :: Monad m => ListT m a -> m Bool
null :: ListT m a -> m Bool
null =
  (Maybe (a, ListT m a) -> Bool)
-> m (Maybe (a, ListT m a)) -> m Bool
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Bool -> ((a, ListT m a) -> Bool) -> Maybe (a, ListT m a) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (Bool -> (a, ListT m a) -> Bool
forall a b. a -> b -> a
const Bool
False)) (m (Maybe (a, ListT m a)) -> m Bool)
-> (ListT m a -> m (Maybe (a, ListT m a))) -> ListT m a -> m Bool
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons

-- |
-- Execute, applying a left fold.
{-# INLINABLE fold #-}
fold :: Monad m => (r -> a -> m r) -> r -> ListT m a -> m r
fold :: (r -> a -> m r) -> r -> ListT m a -> m r
fold s :: r -> a -> m r
s r :: r
r = 
  ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons (ListT m a -> m (Maybe (a, ListT m a)))
-> (Maybe (a, ListT m a) -> m r) -> ListT m a -> m r
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> m r -> ((a, ListT m a) -> m r) -> Maybe (a, ListT m a) -> m r
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
r) (\(h :: a
h, t :: ListT m a
t) -> r -> a -> m r
s r
r a
h m r -> (r -> m r) -> m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \r' :: r
r' -> (r -> a -> m r) -> r -> ListT m a -> m r
forall (m :: * -> *) r a.
Monad m =>
(r -> a -> m r) -> r -> ListT m a -> m r
fold r -> a -> m r
s r
r' ListT m a
t)

-- |
-- A version of 'fold', which allows early termination.
{-# INLINABLE foldMaybe #-}
foldMaybe :: Monad m => (r -> a -> m (Maybe r)) -> r -> ListT m a -> m r
foldMaybe :: (r -> a -> m (Maybe r)) -> r -> ListT m a -> m r
foldMaybe s :: r -> a -> m (Maybe r)
s r :: r
r l :: ListT m a
l =
  (Maybe r -> r) -> m (Maybe r) -> m r
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (r -> (r -> r) -> Maybe r -> r
forall b a. b -> (a -> b) -> Maybe a -> b
maybe r
r r -> r
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id) (m (Maybe r) -> m r) -> m (Maybe r) -> m r
forall a b. (a -> b) -> a -> b
$ MaybeT m r -> m (Maybe r)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m r -> m (Maybe r)) -> MaybeT m r -> m (Maybe r)
forall a b. (a -> b) -> a -> b
$ do
    (h :: a
h, t :: ListT m a
t) <- m (Maybe (a, ListT m a)) -> MaybeT m (a, ListT m a)
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe (a, ListT m a)) -> MaybeT m (a, ListT m a))
-> m (Maybe (a, ListT m a)) -> MaybeT m (a, ListT m a)
forall a b. (a -> b) -> a -> b
$ ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons ListT m a
l
    r
r' <- m (Maybe r) -> MaybeT m r
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe r) -> MaybeT m r) -> m (Maybe r) -> MaybeT m r
forall a b. (a -> b) -> a -> b
$ r -> a -> m (Maybe r)
s r
r a
h
    m r -> MaybeT m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> MaybeT m r) -> m r -> MaybeT m r
forall a b. (a -> b) -> a -> b
$ (r -> a -> m (Maybe r)) -> r -> ListT m a -> m r
forall (m :: * -> *) r a.
Monad m =>
(r -> a -> m (Maybe r)) -> r -> ListT m a -> m r
foldMaybe r -> a -> m (Maybe r)
s r
r' ListT m a
t

-- |
-- Apply a left fold abstraction from the \"foldl\" package.
applyFoldM :: Monad m => FoldM m i o -> ListT m i -> m o
applyFoldM :: FoldM m i o -> ListT m i -> m o
applyFoldM (FoldM step :: x -> i -> m x
step init :: m x
init extract :: x -> m o
extract) lt :: ListT m i
lt = do
  x
a <- m x
init
  x
b <- (x -> i -> m x) -> x -> ListT m i -> m x
forall (m :: * -> *) r a.
Monad m =>
(r -> a -> m r) -> r -> ListT m a -> m r
fold x -> i -> m x
step x
a ListT m i
lt
  x -> m o
extract x
b

-- |
-- Execute, folding to a list.
{-# INLINABLE toList #-}
toList :: Monad m => ListT m a -> m [a]
toList :: ListT m a -> m [a]
toList =
  (([a] -> [a]) -> [a]) -> m ([a] -> [a]) -> m [a]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ []) (m ([a] -> [a]) -> m [a])
-> (ListT m a -> m ([a] -> [a])) -> ListT m a -> m [a]
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (([a] -> [a]) -> a -> m ([a] -> [a]))
-> ([a] -> [a]) -> ListT m a -> m ([a] -> [a])
forall (m :: * -> *) r a.
Monad m =>
(r -> a -> m r) -> r -> ListT m a -> m r
fold (\f :: [a] -> [a]
f e :: a
e -> ([a] -> [a]) -> m ([a] -> [a])
forall (m :: * -> *) a. Monad m => a -> m a
return (([a] -> [a]) -> m ([a] -> [a])) -> ([a] -> [a]) -> m ([a] -> [a])
forall a b. (a -> b) -> a -> b
$ [a] -> [a]
f ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a
e a -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) [a] -> [a]
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

-- |
-- Execute, folding to a list in the reverse order.
-- Performs more efficiently than 'toList'.
{-# INLINABLE toReverseList #-}
toReverseList :: Monad m => ListT m a -> m [a]
toReverseList :: ListT m a -> m [a]
toReverseList =
  ([a] -> a -> m [a]) -> [a] -> ListT m a -> m [a]
forall (m :: * -> *) r a.
Monad m =>
(r -> a -> m r) -> r -> ListT m a -> m r
ListT.fold (\l :: [a]
l -> [a] -> m [a]
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> m [a]) -> (a -> [a]) -> a -> m [a]
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
l)) []

-- |
-- Execute, traversing the stream with a side effect in the inner monad. 
{-# INLINABLE traverse_ #-}
traverse_ :: Monad m => (a -> m ()) -> ListT m a -> m ()
traverse_ :: (a -> m ()) -> ListT m a -> m ()
traverse_ f :: a -> m ()
f =
  (() -> a -> m ()) -> () -> ListT m a -> m ()
forall (m :: * -> *) r a.
Monad m =>
(r -> a -> m r) -> r -> ListT m a -> m r
fold ((a -> m ()) -> () -> a -> m ()
forall a b. a -> b -> a
const a -> m ()
f) ()

-- |
-- Execute, consuming a list of the specified length and returning the remainder stream.
{-# INLINABLE splitAt #-}
splitAt :: Monad m => Int -> ListT m a -> m ([a], ListT m a)
splitAt :: Int -> ListT m a -> m ([a], ListT m a)
splitAt =
  \case
    n :: Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 -> \l :: ListT m a
l ->
      ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons ListT m a
l m (Maybe (a, ListT m a))
-> (Maybe (a, ListT m a) -> m ([a], ListT m a))
-> m ([a], ListT m a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Nothing -> ([a], ListT m a) -> m ([a], ListT m a)
forall (m :: * -> *) a. Monad m => a -> m a
return ([], ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero)
        Just (h :: a
h, t :: ListT m a
t) -> do
          (r1 :: [a]
r1, r2 :: ListT m a
r2) <- Int -> ListT m a -> m ([a], ListT m a)
forall (m :: * -> *) a.
Monad m =>
Int -> ListT m a -> m ([a], ListT m a)
splitAt (Int -> Int
forall a. Enum a => a -> a
pred Int
n) ListT m a
t
          ([a], ListT m a) -> m ([a], ListT m a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
h a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
r1, ListT m a
r2)
    _ -> \l :: ListT m a
l -> 
      ([a], ListT m a) -> m ([a], ListT m a)
forall (m :: * -> *) a. Monad m => a -> m a
return ([], ListT m a
l)


-- * Construction
-------------------------

-- |
-- Prepend an element.
cons :: Monad m => a -> ListT m a -> ListT m a
cons :: a -> ListT m a -> ListT m a
cons h :: a
h t :: ListT m a
t =
  m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> m (Maybe (a, ListT m a)) -> ListT m a
forall a b. (a -> b) -> a -> b
$ Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, ListT m a) -> Maybe (a, ListT m a)
forall a. a -> Maybe a
Just (a
h, ListT m a
t))

-- |
-- Construct from any foldable.
{-# INLINABLE fromFoldable #-}
fromFoldable :: (Monad m, Foldable f) => f a -> ListT m a
fromFoldable :: f a -> ListT m a
fromFoldable = 
  (a -> ListT m a -> ListT m a) -> ListT m a -> f a -> ListT m a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero

-- |
-- Construct from an MVar, interpreting the value of Nothing as the end.
fromMVar :: (MonadIO m) => MVar (Maybe a) -> ListT m a
fromMVar :: MVar (Maybe a) -> ListT m a
fromMVar v :: MVar (Maybe a)
v =
  (ListT m a -> ListT m a) -> ListT m a
forall a. (a -> a) -> a
fix ((ListT m a -> ListT m a) -> ListT m a)
-> (ListT m a -> ListT m a) -> ListT m a
forall a b. (a -> b) -> a -> b
$ \loop :: ListT m a
loop -> IO (Maybe a) -> ListT m (Maybe a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (MVar (Maybe a) -> IO (Maybe a)
forall a. MVar a -> IO a
takeMVar MVar (Maybe a)
v) ListT m (Maybe a) -> (Maybe a -> ListT m a) -> ListT m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ListT m a -> (a -> ListT m a) -> Maybe a -> ListT m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero ((a -> ListT m a -> ListT m a) -> ListT m a -> a -> ListT m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons ListT m a
loop)

-- |
-- Construct by unfolding a pure data structure.
{-# INLINABLE unfold #-}
unfold :: Monad m => (b -> Maybe (a, b)) -> b -> ListT m a
unfold :: (b -> Maybe (a, b)) -> b -> ListT m a
unfold f :: b -> Maybe (a, b)
f s :: b
s =
  ListT m a -> ((a, b) -> ListT m a) -> Maybe (a, b) -> ListT m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero (\(h :: a
h, t :: b
t) -> a -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons a
h ((b -> Maybe (a, b)) -> b -> ListT m a
forall (m :: * -> *) b a.
Monad m =>
(b -> Maybe (a, b)) -> b -> ListT m a
unfold b -> Maybe (a, b)
f b
t)) (b -> Maybe (a, b)
f b
s)

-- |
-- Construct by unfolding a monadic data structure
--
-- This is the most memory-efficient way to construct ListT where
-- the length depends on the inner monad.
{-# INLINABLE unfoldM #-}
unfoldM :: Monad m => (b -> m (Maybe (a, b))) -> b -> ListT m a
unfoldM :: (b -> m (Maybe (a, b))) -> b -> ListT m a
unfoldM f :: b -> m (Maybe (a, b))
f = b -> ListT m a
go where
  go :: b -> ListT m a
go s :: b
s = m (Maybe (a, ListT m a)) -> ListT m a
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (a, ListT m a)) -> ListT m a)
-> m (Maybe (a, ListT m a)) -> ListT m a
forall a b. (a -> b) -> a -> b
$ b -> m (Maybe (a, b))
f b
s m (Maybe (a, b))
-> (Maybe (a, b) -> m (Maybe (a, ListT m a)))
-> m (Maybe (a, ListT m a))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Nothing -> Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (a, ListT m a)
forall a. Maybe a
Nothing
    Just (a :: a
a,r :: b
r) -> Maybe (a, ListT m a) -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, ListT m a) -> Maybe (a, ListT m a)
forall a. a -> Maybe a
Just (a
a, b -> ListT m a
go b
r))

-- |
-- Produce an infinite stream.
{-# INLINABLE repeat #-}
repeat :: Monad m => a -> ListT m a
repeat :: a -> ListT m a
repeat = 
  (ListT m a -> ListT m a) -> ListT m a
forall a. (a -> a) -> a
fix ((ListT m a -> ListT m a) -> ListT m a)
-> (a -> ListT m a -> ListT m a) -> a -> ListT m a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons


-- * Transformation
-------------------------

-- |
-- A transformation,
-- which traverses the stream with an action in the inner monad.
{-# INLINABLE traverse #-}
traverse :: Monad m => (a -> m b) -> ListT m a -> ListT m b
traverse :: (a -> m b) -> ListT m a -> ListT m b
traverse f :: a -> m b
f s :: ListT m a
s =
  m (Maybe (a, ListT m a)) -> ListT m (Maybe (a, ListT m a))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons ListT m a
s) ListT m (Maybe (a, ListT m a))
-> (Maybe (a, ListT m a) -> ListT m (Maybe b)) -> ListT m (Maybe b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= 
  ((a, ListT m a) -> ListT m b)
-> Maybe (a, ListT m a) -> ListT m (Maybe b)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(h :: a
h, t :: ListT m a
t) -> m b -> ListT m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (a -> m b
f a
h) ListT m b -> (b -> ListT m b) -> ListT m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \h' :: b
h' -> b -> ListT m b -> ListT m b
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons b
h' ((a -> m b) -> ListT m a -> ListT m b
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> ListT m a -> ListT m b
traverse a -> m b
f ListT m a
t)) ListT m (Maybe b) -> (Maybe b -> ListT m b) -> ListT m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
  ListT m b -> (b -> ListT m b) -> Maybe b -> ListT m b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ListT m b
forall (m :: * -> *) a. MonadPlus m => m a
mzero b -> ListT m b
forall (m :: * -> *) a. Monad m => a -> m a
return

-- |
-- A transformation,
-- reproducing the behaviour of @Data.List.'Data.List.take'@.
{-# INLINABLE take #-}
take :: Monad m => Int -> ListT m a -> ListT m a
take :: Int -> ListT m a -> ListT m a
take =
  \case
    n :: Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 -> \t :: ListT m a
t ->
      m (Maybe (a, ListT m a)) -> ListT m (Maybe (a, ListT m a))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons ListT m a
t) ListT m (Maybe (a, ListT m a))
-> (Maybe (a, ListT m a) -> ListT m a) -> ListT m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= 
        \case
          Nothing -> ListT m a
t
          Just (h :: a
h, t :: ListT m a
t) -> a -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons a
h (Int -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => Int -> ListT m a -> ListT m a
take (Int -> Int
forall a. Enum a => a -> a
pred Int
n) ListT m a
t)
    _ ->
      ListT m a -> ListT m a -> ListT m a
forall a b. a -> b -> a
const (ListT m a -> ListT m a -> ListT m a)
-> ListT m a -> ListT m a -> ListT m a
forall a b. (a -> b) -> a -> b
$ ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero

-- |
-- A transformation,
-- reproducing the behaviour of @Data.List.'Data.List.drop'@.
{-# INLINABLE drop #-}
drop :: Monad m => Int -> ListT m a -> ListT m a
drop :: Int -> ListT m a -> ListT m a
drop =
  \case
    n :: Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 ->
      m (Maybe (a, ListT m a)) -> ListT m (Maybe (a, ListT m a))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (a, ListT m a)) -> ListT m (Maybe (a, ListT m a)))
-> (ListT m a -> m (Maybe (a, ListT m a)))
-> ListT m a
-> ListT m (Maybe (a, ListT m a))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ListT m a -> m (Maybe (a, ListT m a))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
uncons (ListT m a -> ListT m (Maybe (a, ListT m a)))
-> (Maybe (a, ListT m a) -> ListT m a) -> ListT m a -> ListT m a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> ListT m a
-> ((a, ListT m a) -> ListT m a)
-> Maybe (a, ListT m a)
-> ListT m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ListT m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero (Int -> ListT m a -> ListT m a
forall (m :: * -> *) a. Monad m => Int -> ListT m a -> ListT m a
drop (Int -> Int
forall a. Enum a => a -> a
pred Int
n) (ListT m a -> ListT m a)
-> ((a, ListT m a) -> ListT m a) -> (a, ListT m a) -> ListT m a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, ListT m a) -> ListT m a
forall a b. (a, b) -> b
snd)
    _ ->
      ListT m a -> ListT m a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

-- |
-- A transformation,
-- which slices a list into chunks of the specified length.
{-# INLINABLE slice #-}
slice :: Monad m => Int -> ListT m a -> ListT m [a]
slice :: Int -> ListT m a -> ListT m [a]
slice n :: Int
n l :: ListT m a
l = 
  do
    (h :: [a]
h, t :: ListT m a
t) <- m ([a], ListT m a) -> ListT m ([a], ListT m a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ([a], ListT m a) -> ListT m ([a], ListT m a))
-> m ([a], ListT m a) -> ListT m ([a], ListT m a)
forall a b. (a -> b) -> a -> b
$ Int -> ListT m a -> m ([a], ListT m a)
forall (m :: * -> *) a.
Monad m =>
Int -> ListT m a -> m ([a], ListT m a)
splitAt Int
n ListT m a
l
    case [a]
h of
      [] -> ListT m [a]
forall (m :: * -> *) a. MonadPlus m => m a
mzero
      _ -> [a] -> ListT m [a] -> ListT m [a]
forall (m :: * -> *) a. Monad m => a -> ListT m a -> ListT m a
cons [a]
h (Int -> ListT m a -> ListT m [a]
forall (m :: * -> *) a. Monad m => Int -> ListT m a -> ListT m [a]
slice Int
n ListT m a
t)