Created
April 17, 2013 04:40
-
-
Save k0001/5401844 to your computer and use it in GitHub Desktop.
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
{-# LANGUAGE OverloadedStrings #-} | |
module Main (main) where | |
import Control.Applicative | |
import qualified Data.Attoparsec.Text as A | |
import qualified Data.Text as T | |
import Control.Monad | |
import Control.Monad.Trans.Class | |
import Control.Monad.ST | |
import Control.Proxy ((>->)) | |
import qualified Control.Proxy as P | |
import qualified Control.Proxy.Trans.Either as P | |
import Control.Proxy.Parse (parse, spoil, ParseP) | |
import qualified Control.Proxy.Attoparsec as PA | |
digit :: A.Parser Int | |
digit = read . (:"") <$> A.digit | |
sourceFine :: (Monad m, P.Proxy p) => () -> P.Producer p T.Text m () | |
sourceFine = P.fromListS ["12","3"] | |
sourceBad :: (Monad m, P.Proxy p) => () -> P.Producer p T.Text m () | |
sourceBad = P.fromListS ["1x3","4"] | |
-- | For each digit @n@ received from upstream, send downstream @(n, odd n)@. | |
oddities | |
:: P.Proxy p | |
=> () -> P.Pipe (ParseP s T.Text (P.EitherP PA.ParserError p)) | |
(Maybe T.Text) (Int, Bool) (ST s) b | |
oddities () = forever $ do | |
n <- PA.parseD digit | |
P.respond (n, odd n) | |
-- | Like 'oddities', but skips non-digit characters instead of aborting. | |
odditiesMaybe | |
:: P.Proxy p | |
=> () -> P.Pipe (ParseP s T.Text p) (Maybe T.Text) (Int, Bool) (ST s) () | |
odditiesMaybe () = do | |
mn <- PA.maybeParseD digit | |
case mn of | |
Just n -> do P.respond (n, odd n) | |
odditiesMaybe () | |
Nothing -> do nskipped <- PA.skipN 1 | |
if nskipped == 0 | |
then return () | |
else odditiesMaybe () | |
-- | Like 'odditiesMaybe', but also prints an error message each time a | |
-- non-digit character is found. | |
odditiesEither | |
:: P.Proxy p | |
=> () -> ParseP RealWorld T.Text p () (Maybe T.Text) () (Int, Bool) IO () | |
odditiesEither () = do | |
en <- spoil $ PA.eitherParseD digit | |
case en of | |
Right n -> do P.respond (n, odd n) | |
odditiesEither () | |
Left e -> do lift . putStrLn $ "Skipping parsing error: " ++ show e | |
nskipped <- spoil $ PA.skipN 1 | |
if nskipped == 0 | |
then return () | |
else odditiesEither () | |
main :: IO () | |
main = do | |
putStrLn "*** Using 'sourceFine' ***" | |
putStrLn "--------------------" | |
putStrLn "* oddities" | |
er <- P.runProxy . P.runEitherK $ spoil . parse id sourceFine oddities >-> P.printD | |
case er of | |
Left e -> putStrLn $ "Bad oddities: " ++ show e | |
Right _ -> return () | |
putStrLn "--------------------" | |
putStrLn "* odditiesEither" | |
P.runProxy $ parse spoil sourceFine odditiesEither >-> P.printD | |
putStrLn "--------------------" | |
putStrLn "* odditiesMaybe" | |
P.runProxy $ spoil . parse id sourceFine odditiesMaybe >-> P.printD | |
putStrLn "\n*** Using 'sourceBad' ***" | |
-- the same code as above follows, except using 'sourceBad' instead of 'sourceFine'. | |
putStrLn "--------------------" | |
putStrLn "* oddities" | |
er <- P.runProxy . P.runEitherK $ spoil . parse id sourceBad oddities >-> P.printD | |
case er of | |
Left e -> putStrLn $ "Bad oddities: " ++ show e | |
Right _ -> return () | |
putStrLn "--------------------" | |
putStrLn "* odditiesEither" | |
P.runProxy $ parse spoil sourceBad odditiesEither >-> P.printD | |
putStrLn "--------------------" | |
putStrLn "* odditiesMaybe" | |
P.runProxy $ spoil . parse id sourceBad odditiesMaybe >-> P.printD |
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
*** Using 'sourceFine' *** | |
-------------------- | |
* oddities | |
(1,True) | |
(2,False) | |
(3,True) | |
Bad oddities: ParserError {errorContexts = ["digit","demandInput"], errorMessage = "not enough input"} | |
-------------------- | |
* odditiesEither | |
(1,True) | |
(2,False) | |
(3,True) | |
Skipping parsing error: ParserError {errorContexts = ["digit","demandInput"], errorMessage = "not enough input"} | |
-------------------- | |
* odditiesMaybe | |
(1,True) | |
(2,False) | |
(3,True) | |
*** Using 'sourceBad' *** | |
-------------------- | |
* oddities | |
(1,True) | |
Bad oddities: ParserError {errorContexts = ["digit"], errorMessage = "Failed reading: satisfy"} | |
-------------------- | |
* odditiesEither | |
(1,True) | |
Skipping parsing error: ParserError {errorContexts = ["digit"], errorMessage = "Failed reading: satisfy"} | |
(3,True) | |
(4,False) | |
Skipping parsing error: ParserError {errorContexts = ["digit","demandInput"], errorMessage = "not enough input"} | |
-------------------- | |
* odditiesMaybe | |
(1,True) | |
(3,True) | |
(4,False) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment