module Sound.MIDI.Writer.Status (
module Sound.MIDI.Writer.Status,
lift,
) where
import Sound.MIDI.Parser.Status (Channel)
import qualified Data.Monoid.State as State
import qualified Data.Monoid.Reader as Reader
import qualified Data.Monoid.Transformer as Trans
import Data.Monoid.Transformer (lift, )
import Data.Monoid (Monoid, mempty, mappend, mconcat, )
import Sound.MIDI.Monoid (genAppend, genConcat, )
type Status = Maybe (Int,Channel)
newtype T writer =
Cons {decons :: Reader.T Bool (State.T (Maybe Status) writer)}
instance Monoid writer => Monoid (T writer) where
mempty = Cons $ mempty
mappend = genAppend Cons decons
mconcat = genConcat Cons decons
change :: (Monoid writer) => Status -> writer -> T writer
change x emit =
Cons $
Reader.Cons $ \b ->
State.Cons $ \my ->
let mx = Just x
in (if not b || mx/=my then emit else mempty, mx)
clear :: (Monoid writer) => T writer
clear = Cons $ lift $ State.put Nothing
instance Trans.C T where
lift = fromWriter
fromWriter :: (Monoid writer) => writer -> T writer
fromWriter = Cons . lift . lift
toWriter :: (Monoid writer) => Bool -> T writer -> writer
toWriter withStatus =
State.evaluate Nothing . flip Reader.run withStatus . decons
toWriterWithStatus :: (Monoid writer) => T writer -> writer
toWriterWithStatus = toWriter True
toWriterWithoutStatus :: (Monoid writer) => T writer -> writer
toWriterWithoutStatus = toWriter False