{-# LANGUAGE BlockArguments #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Data.Parse (Parse, parse, unparse, (>>!)) where

import Control.Applicative (empty)
import Control.Monad ((>=>))
import Control.Monad.StateT (StateT(..))

type Parse s = StateT s Maybe

parse :: (s -> Maybe (a, s)) -> Parse s a
parse :: (s -> Maybe (a, s)) -> Parse s a
parse = (s -> Maybe (a, s)) -> Parse s a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT

unparse :: Parse s a -> s -> Maybe (a, s)
unparse :: Parse s a -> s -> Maybe (a, s)
unparse = Parse s a -> s -> Maybe (a, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT

(>>!) :: Parse s a -> Parse s b -> Parse s a
Parse s a
p >>! :: Parse s a -> Parse s b -> Parse s a
>>! Parse s b
nla = (s -> Maybe (a, s)) -> Parse s a
forall s a. (s -> Maybe (a, s)) -> Parse s a
parse ((s -> Maybe (a, s)) -> Parse s a)
-> (s -> Maybe (a, s)) -> Parse s a
forall a b. (a -> b) -> a -> b
$ Parse s a -> s -> Maybe (a, s)
forall s a. Parse s a -> s -> Maybe (a, s)
unparse Parse s a
p (s -> Maybe (a, s))
-> ((a, s) -> Maybe (a, s)) -> s -> Maybe (a, s)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \r :: (a, s)
r@(a
_, s
s) ->
	Maybe (a, s)
-> ((b, s) -> Maybe (a, s)) -> Maybe (b, s) -> Maybe (a, s)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ((a, s) -> Maybe (a, s)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a, s)
r) (Maybe (a, s) -> (b, s) -> Maybe (a, s)
forall a b. a -> b -> a
const Maybe (a, s)
forall (f :: * -> *) a. Alternative f => f a
empty) (Maybe (b, s) -> Maybe (a, s)) -> Maybe (b, s) -> Maybe (a, s)
forall a b. (a -> b) -> a -> b
$ Parse s b
nla Parse s b -> s -> Maybe (b, s)
forall s a. Parse s a -> s -> Maybe (a, s)
`unparse` s
s