Last active
December 17, 2015 23:48
-
-
Save Davorak/5691458 to your computer and use it in GitHub Desktop.
Examples of resumable parsers with pipes-parse a Haskell package. Each example explains its purpose in the comments above it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Proxy | |
import Control.Proxy.Trans.State | |
import Control.Proxy.Parse | |
import Control.Monad | |
chunkLine' | |
:: (Monad m, Proxy p) => | |
() -> StateP [Char] p () (Maybe Char) a [Char] m () | |
chunkLine' () = loop | |
where | |
loop = do | |
as <- (passWhile (/='\n') >-> evalStateK mempty drawAll) () | |
endOfLine <- (draw) -- remove '\n' | |
case endOfLine of | |
Nothing -> (unDraws) (reverse as) >> return () | |
Just '\n' -> do | |
respond as | |
eof <- isEndOfInput | |
unless eof loop | |
unDraws :: (Monad m, Proxy p) => [a] -> StateP [a] p x' x y' y m () | |
unDraws = mapM_ unDraw | |
{- | Chunk a stream of `Char`s in to lines leaving unfinished lines in the | |
- buffer. Then resume pipeline with new input. | |
- | |
- >>> main | |
- "Take steam of `Char`s and chunk them into lines until end of in put saving leftovers" | |
- "hi" | |
- "you" | |
- "there" | |
- "Now rerun the pipe with saved buffers and the extra input \"hi\nyou\nthere\nnow\"" | |
- "now" | |
- "how's" | |
- "life" | |
- ((),"") | |
-} | |
example1 = do | |
print "Take steam of `Char`s and chunk them into lines until end of in put saving leftovers" | |
(_, buffers) <- runProxy | |
$ runStateK mempty | |
$ wrap . (fromListS "hi\nyou\nthere\nnow") | |
>-> wrap . (chunkLine') >-> unwrap >-> printD | |
putStrLn $ "The buffers currently are: " ++ show buffers | |
print "Now rerun the pipe with saved buffers and the extra input \"hi\nyou\nthere\nnow\"" | |
runProxy $ runStateK "now" | |
$ wrap . (fromListS "\nhow's\nlife\n") | |
>-> wrap . (chunkLine') >-> unwrap >-> printD | |
-- | Fake function to count spelling errors on a line | |
countSpellingErrors x = length x `div` 3 | |
partition ln overlap () = loop | |
where | |
loop = do | |
mes <- drawN ln () | |
case mes of | |
Nothing -> return () | |
Just es -> do | |
mapM unDraw $ drop (ln - overlap) es | |
respond es | |
eof <- isEndOfInput | |
unless eof loop | |
{- | drawN n pulls n items from the stream if it fails in drawing n items it | |
- pushes them back to the stream. | |
-} | |
drawN n0 () = loop n0 [] | |
where | |
loop 0 as = return $ Just (reverse as) | |
loop n as = do | |
ma <- draw | |
case ma of | |
Nothing -> unDraws as >> return Nothing | |
Just a -> loop (n - 1) (a:as) | |
{- | Chunk a stream of `Char`'s into lines. Transform into a stream of spelling | |
- errors per line then partition stream with n-1 overlap for later convolution. | |
- | |
- > example2 | |
- "Chunk steam of `Char`s into lines, transform into a stream of spelling per line then partition into list of 2 with 1(n - 1) overlap for latter convolution." | |
- [2,3] | |
- [3,5] | |
- The buffers currently are: ("ow",[5]) | |
- "Continue parsing with both old buffers and new input." | |
- [5,3] | |
- [3,5] | |
- [5,4] | |
- [4,9] | |
- ((),("",[9])) | |
-} | |
example2 = do | |
print "Chunk steam of `Char`s into lines, transform into a stream of spelling per line then partition into list of 2 with 1(n - 1) overlap for latter convolution." | |
(_, buffers) <- runProxy $ runStateK mempty | |
$ wrap . (fromListS "hi\nyou\nthere\now") | |
>-> wrap . (zoom _fst . chunkLine') | |
>-> fmapPull (mapD length) | |
>-> (zoom _snd . partition 2 1) | |
>-> printD | |
putStrLn $ "The buffers currently are: " ++ show buffers | |
print "Continue parsing with both old buffers and new input." | |
runProxy $ runStateK ("now",[5]) | |
$ wrap . (fromListS "\nhow's\nlife\nrecently?\n") | |
>-> wrap . (zoom _fst . chunkLine') | |
>-> fmapPull (mapD length) | |
>-> (zoom _snd . partition 2 1) | |
>-> printD |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment