midi-0.0.7: src/Sound/MIDI/ParserState.hs
{- |
Very similar to "Sound.MIDI.Parser".
-}
module Sound.MIDI.ParserState
(T, zeroOrMore, oneOrMore, StateT(..), ) where
import qualified Sound.MIDI.Parser as Parser
import Control.Monad.State (StateT(..), mapStateT, liftM2, mplus, )
type T st s = StateT st (Parser.T s)
{- |
Wadler's force function
'force' guarantees that the parser does not fail.
Thus it makes parsing more lazy.
However if the original parser fails though,
then we get an unrecoverable /irrefutable pattern/ error on 'Just'.
-}
force :: T st s a -> T st s a
force = mapStateT Parser.force
zeroOrMore :: T st s a -> T st s [a]
zeroOrMore p = force $ oneOrMore p `mplus` return []
oneOrMore :: T st s a -> T st s [a]
oneOrMore p = liftM2 (:) p (zeroOrMore p)