module System.Console.Quickterm.Deserializer
( Deserializer (..)
, tryConvert
) where
import Control.Applicative
import Control.Monad
newtype Deserializer a = Deserializer { deserialize :: [Char] -> Int -> [(a,[Char],Int)] }
instance Functor Deserializer where
fmap f d = Deserializer $ \st p -> fmap (\(a,st',p') -> (f a,st',p')) (deserialize d st p)
instance Applicative Deserializer where
pure a = Deserializer $ \st p -> [(a,st,p)]
f <*> d = Deserializer $ \st p -> deserialize f st p
>>= \(g,st',p') -> deserialize d st' p'
>>= \(a,st'',p'') -> return (g a,st'',p'')
instance Alternative Deserializer where
empty = Deserializer (const (const empty))
d <|> h = Deserializer $ \st p -> deserialize d st p <|> deserialize h st p
instance Monad Deserializer where
return = pure
d >>= f = Deserializer $ \st p -> deserialize d st p >>= \(d',st',p') -> deserialize (f d') st' p'
instance MonadPlus Deserializer where
mzero = empty
mplus = (<|>)
tryConvert :: (String -> [(a,Int)]) -> Deserializer a
tryConvert f = Deserializer $ \st p -> (\(a,i) -> (a,[],p+i)) <$> f st