{- |
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)