module Sound.MIDI.Parser.Status
(T, Status, set, get, run, lift,
Channel, fromChannel, toChannel, ) where
import qualified Sound.MIDI.Parser.Class as Parser
import qualified Control.Monad.Exception.Synchronous as Sync
import qualified Control.Monad.Trans.State as State
import qualified Control.Monad.Trans.Class as Trans
import Control.Monad.Trans.State (StateT, evalStateT, )
import Control.Monad (liftM, )
import qualified Test.QuickCheck as QC
import Test.QuickCheck (Arbitrary(arbitrary, shrink), )
import Sound.MIDI.Utility (checkRange, )
import Data.Ix (Ix)
type T parser = StateT Status parser
type Status = Maybe (Int,Channel)
set :: Monad parser => Status -> Parser.Fragile (T parser) ()
set = Trans.lift . State.put
get :: Monad parser => Parser.Fragile (T parser) Status
get = Trans.lift State.get
run :: Monad parser => T parser a -> parser a
run = flip evalStateT Nothing
lift :: Monad parser => Parser.Fragile parser a -> Parser.Fragile (T parser) a
lift = Sync.mapExceptionalT Trans.lift
newtype Channel = Channel {fromChannel :: Int} deriving (Show, Eq, Ord, Ix)
toChannel :: Int -> Channel
toChannel = checkRange "Channel" Channel
instance Enum Channel where
toEnum = toChannel
fromEnum = fromChannel
instance Bounded Channel where
minBound = Channel 0
maxBound = Channel 15
instance Arbitrary Channel where
arbitrary = liftM toChannel $ QC.choose (0,15)
shrink = map (toChannel . flip mod 16) . shrink . fromChannel