{-# OPTIONS 
            -fglasgow-exts
   #-}

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances, ScopedTypeVariables #-}

-- Search for -fallow-undecidable-instances to see why this is needed

-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Monad.WriterX.Class
-- Copyright   :  (c) Mark Snyder 2008.
-- License     :  BSD-style
-- Maintainer  :  Mark Snyder, marks@ittc.ku.edu
-- Stability   :  experimental
-- Portability :  non-portable (multi-param classes, functional dependencies)
-----------------------------------------------------------------------------

module Control.Monad.WriterX.Class (
    MonadWriterX(..),
    listensx,
    censorx,
--    Index(..)
  ) where

import Data.Monoid
import Control.Monad.Index
-- ---------------------------------------------------------------------------

class (Monoid w, Monad m, Index ix) => MonadWriterX ix w m | ix m -> w where
    tellx   :: ix -> w -> m ()
    listenx :: ix -> m a -> m (a, w)
    passx   :: ix -> m (a, w -> w) -> m a

listensx :: (MonadWriterX ix w m, Index ix) => ix -> (w -> b) -> m a -> m (a, b)
listensx (ixv::ix) f m = do
    ~(a, w) <- listenx ixv m
    return (a, f w)

censorx :: (MonadWriterX ix w m, Index ix) => ix -> (w -> w) -> m a -> m a
censorx (ixv::ix) f m = passx ixv $ do
    a <- m
    return (a, f)