Skip to content

Instantly share code, notes, and snippets.

@earthengine
Created December 16, 2016 10:34
Show Gist options
  • Save earthengine/b248744922e346dbaad0afa20f5b317c to your computer and use it in GitHub Desktop.
Save earthengine/b248744922e346dbaad0afa20f5b317c to your computer and use it in GitHub Desktop.
Haskell PushParser
module PushParser where
import Data.Monoid
import Control.Applicative
import Control.Monad
{-
t is the type of tokens, r is the type of results.
Empty result set means the parsing do not have a result at the moment.
If the continue parsing function is Nothing, we are in an error state and no more
parsing is possible. Otherwise, we can send a token to it and move forward.
-}
newtype PushParser t r = PushParser ([r], Maybe (t -> PushParser t r))
parse :: PushParser t r -> [t] -> [r]
parse ~(PushParser (rs, _)) [] = rs
parse (PushParser (_,Nothing)) _ = []
parse (PushParser (_,Just f)) (t:ts) = parse (f t) ts
instance Functor (PushParser t) where
fmap f ~(PushParser (r,mg)) = PushParser ((map f r), do {g<-mg; return (fmap f.g)})
instance Applicative (PushParser t) where
pure x = PushParser ([x],Nothing)
pf <*> pv = do
f <- pf
v <- pv
return (f v)
instance Alternative (PushParser t) where
empty = PushParser ([],Nothing)
(PushParser (r1,Nothing)) <|> (PushParser (r2,f)) = PushParser ((r1++r2), f)
(PushParser (r1,f)) <|> (PushParser (r2,Nothing)) = PushParser ((r1++r2), f)
(PushParser (r1,Just f1)) <|> (PushParser (r2,Just f2)) =
PushParser ((r1 ++ r2), Just (\t -> f1 t <|> f2 t))
instance Monad (PushParser t) where
p >>= f = unwrap (fmap f p) where
unwrap ~(PushParser (prs, mf)) =
foldr (<|>) (PushParser ([], do { f<-mf; return (unwrap.f)})) prs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment