module Text.Printer.List
       ( PrintM, Printer, execPrinter
       , token, list
       ) where

import Control.Monad.Trans.Writer (Writer, execWriter, tell)
import Data.DList (DList)
import qualified Data.DList as DList


type PrintM t = Writer (DList t)

type Printer t a = a -> PrintM t ()

token :: Printer t t
token :: forall t. Printer t t
token = DList t -> WriterT (DList t) Identity ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell (DList t -> WriterT (DList t) Identity ())
-> (t -> DList t) -> t -> WriterT (DList t) Identity ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> DList t
forall (m :: * -> *) a. Monad m => a -> m a
return

list :: Printer t [t]
list :: forall t. Printer t [t]
list = (t -> WriterT (DList t) Identity ())
-> [t] -> WriterT (DList t) Identity ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ t -> WriterT (DList t) Identity ()
forall t. Printer t t
token

execPrinter :: Printer t a -> a -> [t]
execPrinter :: forall t a. Printer t a -> a -> [t]
execPrinter Printer t a
p = DList t -> [t]
forall a. DList a -> [a]
DList.toList (DList t -> [t]) -> (a -> DList t) -> a -> [t]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Writer (DList t) () -> DList t
forall w a. Writer w a -> w
execWriter (Writer (DList t) () -> DList t) -> Printer t a -> a -> DList t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer t a
p