{-# LANGUAGE DeriveFunctor #-}

-- | Some useful Monads
module System.FilePattern.Monads(
    Next, runNext, getNext
    ) where

import Control.Applicative
import Prelude

-- | Next is a monad which has a series of elements, and can pull off the next one
newtype Next e a = Next ([e] -> Maybe ([e], a))
    deriving a -> Next e b -> Next e a
(a -> b) -> Next e a -> Next e b
(forall a b. (a -> b) -> Next e a -> Next e b)
-> (forall a b. a -> Next e b -> Next e a) -> Functor (Next e)
forall a b. a -> Next e b -> Next e a
forall a b. (a -> b) -> Next e a -> Next e b
forall e a b. a -> Next e b -> Next e a
forall e a b. (a -> b) -> Next e a -> Next e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Next e b -> Next e a
$c<$ :: forall e a b. a -> Next e b -> Next e a
fmap :: (a -> b) -> Next e a -> Next e b
$cfmap :: forall e a b. (a -> b) -> Next e a -> Next e b
Functor

instance Applicative (Next e) where
    pure :: a -> Next e a
pure a
a = ([e] -> Maybe ([e], a)) -> Next e a
forall e a. ([e] -> Maybe ([e], a)) -> Next e a
Next (([e] -> Maybe ([e], a)) -> Next e a)
-> ([e] -> Maybe ([e], a)) -> Next e a
forall a b. (a -> b) -> a -> b
$ \[e]
es -> ([e], a) -> Maybe ([e], a)
forall a. a -> Maybe a
Just ([e]
es, a
a)
    Next [e] -> Maybe ([e], a -> b)
f <*> :: Next e (a -> b) -> Next e a -> Next e b
<*> Next [e] -> Maybe ([e], a)
x = ([e] -> Maybe ([e], b)) -> Next e b
forall e a. ([e] -> Maybe ([e], a)) -> Next e a
Next (([e] -> Maybe ([e], b)) -> Next e b)
-> ([e] -> Maybe ([e], b)) -> Next e b
forall a b. (a -> b) -> a -> b
$ \[e]
es -> do
        ([e]
es, a -> b
f) <- [e] -> Maybe ([e], a -> b)
f [e]
es
        ([e]
es, a
x) <- [e] -> Maybe ([e], a)
x [e]
es
        ([e], b) -> Maybe ([e], b)
forall a. a -> Maybe a
Just ([e]
es, a -> b
f a
x)

getNext :: Next e e
getNext :: Next e e
getNext = ([e] -> Maybe ([e], e)) -> Next e e
forall e a. ([e] -> Maybe ([e], a)) -> Next e a
Next (([e] -> Maybe ([e], e)) -> Next e e)
-> ([e] -> Maybe ([e], e)) -> Next e e
forall a b. (a -> b) -> a -> b
$ \[e]
x -> case [e]
x of
    e
e:[e]
es -> ([e], e) -> Maybe ([e], e)
forall a. a -> Maybe a
Just ([e]
es, e
e)
    [e]
_ -> Maybe ([e], e)
forall a. Maybe a
Nothing

runNext :: [e] -> Next e a -> Maybe ([e], a)
runNext :: [e] -> Next e a -> Maybe ([e], a)
runNext [e]
ps (Next [e] -> Maybe ([e], a)
f) = [e] -> Maybe ([e], a)
f [e]
ps