-- | Free list monad transformer
module Control.Monad.Trans.List where

-- base
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class
import Data.Functor.Classes

-- transformers
import Control.Monad.Trans.Class

-- mtl
import Control.Monad.Error.Class
import Control.Monad.RWS (MonadRWS, MonadReader, MonadState)
import Control.Monad.Writer

-- exceptions
import Control.Monad.Catch (MonadCatch, MonadThrow)

-- free
import Control.Monad.Trans.Free

-- free-listt
import Control.Applicative.Trans.List qualified as Applicative

{- | The free list monad transformer.

It is implemented as a rose tree (see https://en.wikipedia.org/wiki/Rose_tree)
of computations in @m@.
-}
newtype ListT m a = ListT {forall (m :: * -> *) a. ListT m a -> FreeT [] m a
getListT :: FreeT [] m a}
  deriving
    ( forall a b. a -> ListT m b -> ListT m a
forall a b. (a -> b) -> ListT m a -> ListT m b
forall (m :: * -> *) a b. Functor m => a -> ListT m b -> ListT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ListT m a -> ListT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> ListT m b -> ListT m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> ListT m b -> ListT m a
fmap :: forall a b. (a -> b) -> ListT m a -> ListT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ListT m a -> ListT m b
Functor
    , forall a. a -> ListT m a
forall a b. ListT m a -> ListT m b -> ListT m a
forall a b. ListT m a -> ListT m b -> ListT m b
forall a b. ListT m (a -> b) -> ListT m a -> ListT m b
forall a b c. (a -> b -> c) -> ListT m a -> ListT m b -> ListT m c
forall {m :: * -> *}. Monad m => Functor (ListT m)
forall (m :: * -> *) a. Monad m => a -> ListT m a
forall (m :: * -> *) a b.
Monad m =>
ListT m a -> ListT m b -> ListT m a
forall (m :: * -> *) a b.
Monad m =>
ListT m a -> ListT m b -> ListT m b
forall (m :: * -> *) a b.
Monad m =>
ListT m (a -> b) -> ListT m a -> ListT m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> ListT m a -> ListT m b -> ListT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. ListT m a -> ListT m b -> ListT m a
$c<* :: forall (m :: * -> *) a b.
Monad m =>
ListT m a -> ListT m b -> ListT m a
*> :: forall a b. ListT m a -> ListT m b -> ListT m b
$c*> :: forall (m :: * -> *) a b.
Monad m =>
ListT m a -> ListT m b -> ListT m b
liftA2 :: forall a b c. (a -> b -> c) -> ListT m a -> ListT m b -> ListT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> ListT m a -> ListT m b -> ListT m c
<*> :: forall a b. ListT m (a -> b) -> ListT m a -> ListT m b
$c<*> :: forall (m :: * -> *) a b.
Monad m =>
ListT m (a -> b) -> ListT m a -> ListT m b
pure :: forall a. a -> ListT m a
$cpure :: forall (m :: * -> *) a. Monad m => a -> ListT m a
Applicative
    , forall a. a -> ListT m a
forall a b. ListT m a -> ListT m b -> ListT m b
forall a b. ListT m a -> (a -> ListT m b) -> ListT m b
forall (m :: * -> *). Monad m => Applicative (ListT m)
forall (m :: * -> *) a. Monad m => a -> ListT m a
forall (m :: * -> *) a b.
Monad m =>
ListT m a -> ListT m b -> ListT m b
forall (m :: * -> *) a b.
Monad m =>
ListT m a -> (a -> ListT m b) -> ListT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> ListT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> ListT m a
>> :: forall a b. ListT m a -> ListT m b -> ListT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
ListT m a -> ListT m b -> ListT m b
>>= :: forall a b. ListT m a -> (a -> ListT m b) -> ListT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
ListT m a -> (a -> ListT m b) -> ListT m b
Monad
    , forall a. ListT m a
forall a. ListT m a -> ListT m [a]
forall a. ListT m a -> ListT m a -> ListT m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall {m :: * -> *}. MonadPlus m => Applicative (ListT m)
forall (m :: * -> *) a. MonadPlus m => ListT m a
forall (m :: * -> *) a. MonadPlus m => ListT m a -> ListT m [a]
forall (m :: * -> *) a.
MonadPlus m =>
ListT m a -> ListT m a -> ListT m a
many :: forall a. ListT m a -> ListT m [a]
$cmany :: forall (m :: * -> *) a. MonadPlus m => ListT m a -> ListT m [a]
some :: forall a. ListT m a -> ListT m [a]
$csome :: forall (m :: * -> *) a. MonadPlus m => ListT m a -> ListT m [a]
<|> :: forall a. ListT m a -> ListT m a -> ListT m a
$c<|> :: forall (m :: * -> *) a.
MonadPlus m =>
ListT m a -> ListT m a -> ListT m a
empty :: forall a. ListT m a
$cempty :: forall (m :: * -> *) a. MonadPlus m => ListT m a
Alternative
    , forall a. ListT m a
forall a. ListT m a -> ListT m a -> ListT m a
forall {m :: * -> *}. MonadPlus m => Monad (ListT m)
forall (m :: * -> *). MonadPlus m => Alternative (ListT m)
forall (m :: * -> *) a. MonadPlus m => ListT m a
forall (m :: * -> *) a.
MonadPlus m =>
ListT m a -> ListT m a -> ListT m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
mplus :: forall a. ListT m a -> ListT m a -> ListT m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
ListT m a -> ListT m a -> ListT m a
mzero :: forall a. ListT m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => ListT m a
MonadPlus
    , forall a. IO a -> ListT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall {m :: * -> *}. MonadIO m => Monad (ListT m)
forall (m :: * -> *) a. MonadIO m => IO a -> ListT m a
liftIO :: forall a. IO a -> ListT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> ListT m a
MonadIO
    , forall a. String -> ListT m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall {m :: * -> *}. MonadFail m => Monad (ListT m)
forall (m :: * -> *) a. MonadFail m => String -> ListT m a
fail :: forall a. String -> ListT m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> ListT m a
MonadFail
    , forall (m :: * -> *). Monad m => Monad (ListT m)
forall (m :: * -> *) a. Monad m => m a -> ListT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *). Monad m => Monad (t m))
-> (forall (m :: * -> *) a. Monad m => m a -> t m a)
-> MonadTrans t
lift :: forall (m :: * -> *) a. Monad m => m a -> ListT m a
$clift :: forall (m :: * -> *) a. Monad m => m a -> ListT m a
MonadTrans
    , forall a b. (a -> b -> Bool) -> ListT m a -> ListT m b -> Bool
forall (m :: * -> *) a b.
Eq1 m =>
(a -> b -> Bool) -> ListT m a -> ListT m b -> Bool
forall (f :: * -> *).
(forall a b. (a -> b -> Bool) -> f a -> f b -> Bool) -> Eq1 f
liftEq :: forall a b. (a -> b -> Bool) -> ListT m a -> ListT m b -> Bool
$cliftEq :: forall (m :: * -> *) a b.
Eq1 m =>
(a -> b -> Bool) -> ListT m a -> ListT m b -> Bool
Eq1
    , forall a b.
(a -> b -> Ordering) -> ListT m a -> ListT m b -> Ordering
forall {m :: * -> *}. Ord1 m => Eq1 (ListT m)
forall (m :: * -> *) a b.
Ord1 m =>
(a -> b -> Ordering) -> ListT m a -> ListT m b -> Ordering
forall (f :: * -> *).
Eq1 f
-> (forall a b. (a -> b -> Ordering) -> f a -> f b -> Ordering)
-> Ord1 f
liftCompare :: forall a b.
(a -> b -> Ordering) -> ListT m a -> ListT m b -> Ordering
$cliftCompare :: forall (m :: * -> *) a b.
Ord1 m =>
(a -> b -> Ordering) -> ListT m a -> ListT m b -> Ordering
Ord1
    , forall a. ReadPrec a -> ReadPrec [a] -> ReadPrec [ListT m a]
forall a. ReadPrec a -> ReadPrec [a] -> ReadPrec (ListT m a)
forall a. (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (ListT m a)
forall a. (Int -> ReadS a) -> ReadS [a] -> ReadS [ListT m a]
forall (m :: * -> *) a.
Read1 m =>
ReadPrec a -> ReadPrec [a] -> ReadPrec [ListT m a]
forall (m :: * -> *) a.
Read1 m =>
ReadPrec a -> ReadPrec [a] -> ReadPrec (ListT m a)
forall (m :: * -> *) a.
Read1 m =>
(Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (ListT m a)
forall (m :: * -> *) a.
Read1 m =>
(Int -> ReadS a) -> ReadS [a] -> ReadS [ListT m a]
forall (f :: * -> *).
(forall a. (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a))
-> (forall a. (Int -> ReadS a) -> ReadS [a] -> ReadS [f a])
-> (forall a. ReadPrec a -> ReadPrec [a] -> ReadPrec (f a))
-> (forall a. ReadPrec a -> ReadPrec [a] -> ReadPrec [f a])
-> Read1 f
liftReadListPrec :: forall a. ReadPrec a -> ReadPrec [a] -> ReadPrec [ListT m a]
$cliftReadListPrec :: forall (m :: * -> *) a.
Read1 m =>
ReadPrec a -> ReadPrec [a] -> ReadPrec [ListT m a]
liftReadPrec :: forall a. ReadPrec a -> ReadPrec [a] -> ReadPrec (ListT m a)
$cliftReadPrec :: forall (m :: * -> *) a.
Read1 m =>
ReadPrec a -> ReadPrec [a] -> ReadPrec (ListT m a)
liftReadList :: forall a. (Int -> ReadS a) -> ReadS [a] -> ReadS [ListT m a]
$cliftReadList :: forall (m :: * -> *) a.
Read1 m =>
(Int -> ReadS a) -> ReadS [a] -> ReadS [ListT m a]
liftReadsPrec :: forall a. (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (ListT m a)
$cliftReadsPrec :: forall (m :: * -> *) a.
Read1 m =>
(Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (ListT m a)
Read1
    , forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> ListT m a -> ShowS
forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [ListT m a] -> ShowS
forall (m :: * -> *) a.
Show1 m =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> ListT m a -> ShowS
forall (m :: * -> *) a.
Show1 m =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [ListT m a] -> ShowS
forall (f :: * -> *).
(forall a.
 (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS)
-> (forall a.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [f a] -> ShowS)
-> Show1 f
liftShowList :: forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [ListT m a] -> ShowS
$cliftShowList :: forall (m :: * -> *) a.
Show1 m =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [ListT m a] -> ShowS
liftShowsPrec :: forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> ListT m a -> ShowS
$cliftShowsPrec :: forall (m :: * -> *) a.
Show1 m =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> ListT m a -> ShowS
Show1
    , ListT m a -> ListT m a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (m :: * -> *) a.
(Eq1 m, Eq a) =>
ListT m a -> ListT m a -> Bool
/= :: ListT m a -> ListT m a -> Bool
$c/= :: forall (m :: * -> *) a.
(Eq1 m, Eq a) =>
ListT m a -> ListT m a -> Bool
== :: ListT m a -> ListT m a -> Bool
$c== :: forall (m :: * -> *) a.
(Eq1 m, Eq a) =>
ListT m a -> ListT m a -> Bool
Eq
    , ListT m a -> ListT m a -> Bool
ListT m a -> ListT m a -> Ordering
ListT m a -> ListT m a -> ListT m a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {m :: * -> *} {a}. (Ord1 m, Ord a) => Eq (ListT m a)
forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Bool
forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Ordering
forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> ListT m a
min :: ListT m a -> ListT m a -> ListT m a
$cmin :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> ListT m a
max :: ListT m a -> ListT m a -> ListT m a
$cmax :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> ListT m a
>= :: ListT m a -> ListT m a -> Bool
$c>= :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Bool
> :: ListT m a -> ListT m a -> Bool
$c> :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Bool
<= :: ListT m a -> ListT m a -> Bool
$c<= :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Bool
< :: ListT m a -> ListT m a -> Bool
$c< :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Bool
compare :: ListT m a -> ListT m a -> Ordering
$ccompare :: forall (m :: * -> *) a.
(Ord1 m, Ord a) =>
ListT m a -> ListT m a -> Ordering
Ord
    , ReadPrec [ListT m a]
ReadPrec (ListT m a)
ReadS [ListT m a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall (m :: * -> *) a. (Read1 m, Read a) => ReadPrec [ListT m a]
forall (m :: * -> *) a. (Read1 m, Read a) => ReadPrec (ListT m a)
forall (m :: * -> *) a.
(Read1 m, Read a) =>
Int -> ReadS (ListT m a)
forall (m :: * -> *) a. (Read1 m, Read a) => ReadS [ListT m a]
readListPrec :: ReadPrec [ListT m a]
$creadListPrec :: forall (m :: * -> *) a. (Read1 m, Read a) => ReadPrec [ListT m a]
readPrec :: ReadPrec (ListT m a)
$creadPrec :: forall (m :: * -> *) a. (Read1 m, Read a) => ReadPrec (ListT m a)
readList :: ReadS [ListT m a]
$creadList :: forall (m :: * -> *) a. (Read1 m, Read a) => ReadS [ListT m a]
readsPrec :: Int -> ReadS (ListT m a)
$creadsPrec :: forall (m :: * -> *) a.
(Read1 m, Read a) =>
Int -> ReadS (ListT m a)
Read
    , Int -> ListT m a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: * -> *) a.
(Show1 m, Show a) =>
Int -> ListT m a -> ShowS
forall (m :: * -> *) a. (Show1 m, Show a) => [ListT m a] -> ShowS
forall (m :: * -> *) a. (Show1 m, Show a) => ListT m a -> String
showList :: [ListT m a] -> ShowS
$cshowList :: forall (m :: * -> *) a. (Show1 m, Show a) => [ListT m a] -> ShowS
show :: ListT m a -> String
$cshow :: forall (m :: * -> *) a. (Show1 m, Show a) => ListT m a -> String
showsPrec :: Int -> ListT m a -> ShowS
$cshowsPrec :: forall (m :: * -> *) a.
(Show1 m, Show a) =>
Int -> ListT m a -> ShowS
Show
    , MonadError e
    , MonadState s
    , MonadReader r
    , MonadRWS r w s
    , MonadWriter w
    , forall e a.
(HasCallStack, Exception e) =>
ListT m a -> (e -> ListT m a) -> ListT m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a.
    (HasCallStack, Exception e) =>
    m a -> (e -> m a) -> m a)
-> MonadCatch m
forall {m :: * -> *}. MonadCatch m => MonadThrow (ListT m)
forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
ListT m a -> (e -> ListT m a) -> ListT m a
catch :: forall e a.
(HasCallStack, Exception e) =>
ListT m a -> (e -> ListT m a) -> ListT m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
ListT m a -> (e -> ListT m a) -> ListT m a
MonadCatch
    , forall e a. (HasCallStack, Exception e) => e -> ListT m a
forall (m :: * -> *).
Monad m
-> (forall e a. (HasCallStack, Exception e) => e -> m a)
-> MonadThrow m
forall {m :: * -> *}. MonadThrow m => Monad (ListT m)
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> ListT m a
throwM :: forall e a. (HasCallStack, Exception e) => e -> ListT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> ListT m a
MonadThrow
    )

-- | Flatten all layers of computations to a single one.
flatten :: (Monad m) => ListT m a -> Applicative.ListT m a
flatten :: forall (m :: * -> *) a. Monad m => ListT m a -> ListT m a
flatten = forall (f :: * -> *) a. f [a] -> ListT f a
Applicative.ListT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => ListT m a -> m [a]
runListT

-- | Like 'flatten', but remove the 'Applicative.ListT' wrapper.
runListT :: (Monad m) => ListT m a -> m [a]
runListT :: forall (m :: * -> *) a. Monad m => ListT m a -> m [a]
runListT = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, Monad m) =>
(f (m a) -> m a) -> FreeT f m a -> m a
iterT (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ListT m a -> FreeT [] m a
getListT

-- | Construct a 'ListT' from an effectful list (a single layer).
listT :: (Monad m) => m [a] -> ListT m a
listT :: forall (m :: * -> *) a. Monad m => m [a] -> ListT m a
listT = forall (m :: * -> *) a. FreeT [] m a -> ListT m a
ListT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (m :: * -> *) a.
m (FreeF f a (FreeT f m a)) -> FreeT f m a
FreeT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. f b -> FreeF f a b
Free forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (f :: * -> *) a. Applicative f => a -> f a
pure)

-- | Construct a 'ListT' from a single effectful value.
singleton :: (Functor m) => m a -> ListT m a
singleton :: forall (m :: * -> *) a. Functor m => m a -> ListT m a
singleton = forall (m :: * -> *) a. FreeT [] m a -> ListT m a
ListT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (m :: * -> *) a.
m (FreeF f a (FreeT f m a)) -> FreeT f m a
FreeT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (f :: * -> *) a b. a -> FreeF f a b
Pure