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.Transformer as Trans
import Data.Monoid.Transformer (lift, )
import qualified Data.Monoid.HT as MonoidHT
import Data.Monoid (Monoid, mempty, mappend, mconcat, )
import Sound.MIDI.Monoid (genAppend, genConcat, )
data Uncompressed = Uncompressed
newtype Compressed = Compressed Status
type Status = Maybe (Int,Channel)
newtype T compress writer = Cons {decons :: State.T compress writer}
instance Monoid writer => Monoid (T compress writer) where
mempty = Cons $ mempty
mappend = genAppend Cons decons
mconcat = genConcat Cons decons
class Compression compress where
change :: (Monoid writer) => (Int, Channel) -> writer -> T compress writer
initState :: compress
instance Compression Uncompressed where
change _ emit = Cons $ State.pure emit
initState = Uncompressed
instance Compression Compressed where
change x emit =
Cons $
State.Cons $ \(Compressed my) ->
let mx = Just x
in (MonoidHT.when (mx/=my) emit, Compressed mx)
initState = Compressed Nothing
clear :: (Compression compress, Monoid writer) => T compress writer
clear = Cons $ State.put initState
instance Trans.C (T compress) where
lift = fromWriter
fromWriter :: (Monoid writer) => writer -> T compress writer
fromWriter = Cons . lift
toWriter :: (Compression compress, Monoid writer) => T compress writer -> writer
toWriter = State.evaluate initState . decons
toWriterWithStatus :: (Monoid writer) => T Compressed writer -> writer
toWriterWithStatus = toWriter
toWriterWithoutStatus :: (Monoid writer) => T Uncompressed writer -> writer
toWriterWithoutStatus = toWriter