attoparsec-trans (empty) → 0.1.0.0
raw patch · 4 files changed
+154/−0 lines, 4 filesdep +attoparsecdep +basedep +transformerssetup-changed
Dependencies added: attoparsec, base, transformers
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- attoparsec-trans.cabal +27/−0
- src/Control/Monad/Trans/Parser.hs +105/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Sam Rijs++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ attoparsec-trans.cabal view
@@ -0,0 +1,27 @@+-- Initial attoparsec-trans.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: attoparsec-trans+version: 0.1.0.0+synopsis: Interleaved effects for attoparsec parsers+-- description: +homepage: https://github.com/srijs/haskell-attoparsec-trans+license: MIT+license-file: LICENSE+author: Sam Rijs+maintainer: srijs@airpost.net+-- copyright: +category: Control+build-type: Simple+-- extra-source-files: +cabal-version: >=1.10++library+ exposed-modules: Control.Monad.Trans.Parser+ -- other-modules: + -- other-extensions: + build-depends: base >=4.7 && <4.8,+ transformers >=0.3 && <0.4,+ attoparsec >=0.12 && <0.14+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Control/Monad/Trans/Parser.hs view
@@ -0,0 +1,105 @@+module Control.Monad.Trans.Parser+ (+ -- * Parser types+ ResultM(..), toM+ , ParserT(..), liftIR, liftP+ -- * Running parsers+ , feedM, feedMWith+ , runParserTOnly+ , runParserTWith+ -- ** Result conversion+ , failResultM+ , zeroResultM+ , maybeResultM+ , eitherResultM+ ,) where++import Data.Attoparsec.Combinator (feed)+import Data.Attoparsec.Internal.Types (IResult(..))+import Data.Monoid (Monoid, mempty, (<>))++import Control.Applicative (Applicative, pure, (<*>))+import Control.Monad (MonadPlus, mzero, ap)+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Monad.Trans.Class (MonadTrans, lift)++-- * Parser Types++data ResultM i m r+ = FailM i String+ | DoneM i r+ | PartialM (ParserT i m r)++instance Monad m => Functor (ResultM i m) where+ fmap f (FailM i s) = FailM i s+ fmap f (DoneM i r) = DoneM i (f r)+ fmap f (PartialM p) = PartialM (fmap f p)++toM :: Monad m => IResult i r -> ResultM i m r+toM (Fail i _ s) = FailM i s+toM (Done i r) = DoneM i r+toM (Partial p) = PartialM . ParserT $ return . toM . p++newtype ParserT i m r = ParserT { runParserT :: i -> m (ResultM i m r) }++liftP :: Monad m => (i -> IResult i r) -> ParserT i m r+liftP p = ParserT $ return . toM . p++liftIR :: (Monad m, Monoid i) => IResult i r -> ParserT i m r+liftIR = liftP . feed++instance Monad m => Functor (ParserT i m) where+ fmap f mr = pure f <*> mr++instance Monad m => Applicative (ParserT i m) where+ pure = return+ (<*>) = ap++instance Monad m => Monad (ParserT i m) where+ return r = ParserT $ \i -> return (DoneM i r)+ mr >>= f = ParserT $ \i -> runParserT mr i >>= rec f+ where+ rec f (FailM i s) = return (FailM i s)+ rec f (DoneM i r) = runParserT (f r) i+ rec f (PartialM p) = return . PartialM $ p >>= f++instance MonadTrans (ParserT i) where+ lift mr = ParserT $ \i -> mr >>= return . DoneM i++instance MonadIO m => MonadIO (ParserT i m) where+ liftIO io = lift (liftIO io)++-- * Running parsers++feedM :: (Monad m, Monoid i) => ResultM i m r -> i -> m (ResultM i m r)+feedM (FailM i' s) i = return $ FailM (i' <> i) s+feedM (DoneM i' r) i = return $ DoneM (i' <> i) r+feedM (PartialM p) i = runParserT p i++feedMWith :: (Monad m, Monoid i, Eq i) => m i -> ResultM i m r -> m (ResultM i m r)+feedMWith mi r = mi >>= \i -> case i == mempty of+ True -> return r+ _ -> feedM r i >>= feedMWith mi++runParserTOnly :: Monad m => ParserT i m r -> i -> m (Either String r)+runParserTOnly p i = runParserT p i >>= return . eitherResultM++runParserTWith :: (Monad m, Monoid i, Eq i) => m i -> ParserT i m r -> ParserT i m r+runParserTWith mi p = ParserT $ \i -> runParserT p i >>= feedMWith mi++-- * Result Conversion++failResultM :: Monad m => ResultM i m r -> m r+failResultM = either fail return . eitherResultM++zeroResultM :: MonadPlus m => ResultM i m r -> m r+zeroResultM = maybe mzero return . maybeResultM++maybeResultM :: ResultM i m r -> Maybe r+maybeResultM (DoneM _ r) = Just r+maybeResultM _ = Nothing++eitherResultM :: ResultM i m r -> Either String r+eitherResultM (DoneM _ r) = Right r+eitherResultM (FailM _ s) = Left s+eitherResultM (PartialM _) = Left "Result: incomplete input"