    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 a. a -> DList a
    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