-- | A small prelude used in @zinza@ generated
-- template modules.
module Distribution.ZinzaPrelude
  ( Writer
  , execWriter
  , tell

    -- * Re-exports
  , forM_
  , Generic
  , PackageName
  , Version
  , prettyShow
  ) where

import Distribution.Compat.Prelude
import Prelude ()

import Control.Monad (forM_)
import Distribution.Pretty (prettyShow)
import Distribution.Types.PackageName (PackageName)
import Distribution.Types.Version (Version)

newtype Writer a = W {forall a. Writer a -> ShowS -> (ShowS, a)
unW :: ShowS -> (ShowS, a)}

instance Functor Writer where
  fmap :: forall a b. (a -> b) -> Writer a -> Writer b
fmap = (a -> b) -> Writer a -> Writer b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM

instance Applicative Writer where
  pure :: forall a. a -> Writer a
pure a
x = (ShowS -> (ShowS, a)) -> Writer a
forall a. (ShowS -> (ShowS, a)) -> Writer a
W ((ShowS -> (ShowS, a)) -> Writer a)
-> (ShowS -> (ShowS, a)) -> Writer a
forall a b. (a -> b) -> a -> b
$ \ShowS
ss -> (ShowS
ss, a
x)
  <*> :: forall a b. Writer (a -> b) -> Writer a -> Writer b
(<*>) = Writer (a -> b) -> Writer a -> Writer b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad Writer where
  return :: forall a. a -> Writer a
return = a -> Writer a
forall a. a -> Writer a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Writer a
m >>= :: forall a b. Writer a -> (a -> Writer b) -> Writer b
>>= a -> Writer b
k = (ShowS -> (ShowS, b)) -> Writer b
forall a. (ShowS -> (ShowS, a)) -> Writer a
W ((ShowS -> (ShowS, b)) -> Writer b)
-> (ShowS -> (ShowS, b)) -> Writer b
forall a b. (a -> b) -> a -> b
$ \ShowS
s1 ->
    let (ShowS
s2, a
x) = Writer a -> ShowS -> (ShowS, a)
forall a. Writer a -> ShowS -> (ShowS, a)
unW Writer a
m ShowS
s1
     in Writer b -> ShowS -> (ShowS, b)
forall a. Writer a -> ShowS -> (ShowS, a)
unW (a -> Writer b
k a
x) ShowS
s2
  {-# INLINE (>>=) #-}

execWriter :: Writer a -> String
execWriter :: forall a. Writer a -> String
execWriter Writer a
w = (ShowS, a) -> ShowS
forall a b. (a, b) -> a
fst (Writer a -> ShowS -> (ShowS, a)
forall a. Writer a -> ShowS -> (ShowS, a)
unW Writer a
w ShowS
forall a. a -> a
id) String
""

tell :: String -> Writer ()
tell :: String -> Writer ()
tell String
s = (ShowS -> (ShowS, ())) -> Writer ()
forall a. (ShowS -> (ShowS, a)) -> Writer a
W ((ShowS -> (ShowS, ())) -> Writer ())
-> (ShowS -> (ShowS, ())) -> Writer ()
forall a b. (a -> b) -> a -> b
$ \ShowS
s' -> (ShowS
s' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
s, ())