packages feed

parsec-class (empty) → 1.0.0.0

raw patch · 5 files changed

+150/−0 lines, 5 filesdep +basedep +parsecsetup-changed

Dependencies added: base, parsec

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2018 Peter Simons++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
+ parsec-class.cabal view
@@ -0,0 +1,29 @@+name:          parsec-class+version:       1.0.0.0+synopsis:      Class of types that can be constructed from their text representation+description:   This library provides the type class 'HasParser' as a dual to 'Pretty'.+               Instances of this class provide a parser than can be used to construct the+               type from its text representation.+license:       MIT+license-file:  LICENSE+author:        Peter Simons+maintainer:    simons@cryp.to+tested-with:   GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3+category:      Text+homepage:      https://github.com/peti/parsec-class+bug-reports:   https://github.com/peti/parsec-class/issues+build-type:    Simple+cabal-version: >= 1.10++source-repository head+  type:     git+  location: git://github.com/peti/parsec-class.git++library+  exposed-modules:  Text.Parsec.Class+                    Text.Parsec.Class.Orphans+  hs-source-dirs:   src+  build-depends:    base >= 4.9 && < 5, parsec >= 3+  default-language: Haskell2010+  other-extensions: RankNTypes+                    FlexibleContexts
+ src/Text/Parsec/Class.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE FlexibleContexts, RankNTypes #-}   -- for 'CharParser'++-- | 'HasParser' can be considered a dual to 'Pretty' like 'Read' is to 'Show'.+-- The class provides "Data.Parsec" parsers for its instances that construct+-- the type from its textual representation. Combined with the 'parseM' and+-- 'parse' convenience functions, this class makes parsing simple. Unlike+-- 'Read', Parsec parsers return reasonable error messages in case of failure.+-- Also, there is a rich set of combinators and additional libraries available+-- for re-use.++module Text.Parsec.Class+  ( CharParser, HasParser(parser), ErrorContext+  , parseM, parse+  , -- * Re-exports from Text.Parsec+    module Text.Parsec+  )+  where++import Prelude hiding ( fail )++import Text.Parsec.Class.Orphans ( )   -- TODO: This is unnecessary.++import Control.Exception ( throw )+import Control.Monad.Fail+import Data.Functor.Identity+import Numeric.Natural ( Natural )+import Text.Parsec hiding ( parse )++-- | A simplified 'ParsecT' parser that consumes some kind of character stream+-- without requiring any particular state state.++type CharParser st input m a = Stream st m Char => ParsecT st input m a++-- | Types that are instances of this class can be parsed and constructed from+-- some character based text representation.++class HasParser a where+  parser :: CharParser st input m a++-- | Parsers functions like 'parse' or 'parseM' use this type to provide a+-- helpful context in case the parser failes. Parsec uses the synonym+-- 'SourceName' for the same purpose, but in fact this type doesn't necessarily+-- have to be a file name. It can be any name or identifier. Oftentimes, it+-- it's useful to pass the name of the type that the parser attempted to parse.++type ErrorContext = String++-- | Convenience wrapper around 'runParserT' that uses the 'HasParser' class to+-- determine the desired parser for the given result type. The function reports+-- syntax errors via 'fail'.+--+-- >>> parseM "Natural" "987654321" :: IO Natural+-- 987654321+-- >>> parseM "Natural" "123456789" :: Maybe Natural+-- Just 123456789+--+-- Please note that parsers run this way do not ignore any white space:+--+-- >>> parseM "Natural" " 1" :: Maybe Natural+-- Nothing+-- >>> parseM "Natural" "1 " :: Maybe Natural+-- Nothing++parseM :: (MonadFail m, Stream input m Char, HasParser a) => ErrorContext -> input -> m a+parseM ctx x = runParserT (parser <* eof) () ctx x >>= either (fail . show) return++-- | Convenience wrapper around 'runParser' that uses the 'HasParser' class to+-- determine the desired parser for the given result type. The function reports+-- syntax errors by 'throw'ing 'ParseError'. This approach is inherently impure+-- and complicates error handling greatly. Use this function only on occasions+-- where parser errors are fatal errors that your code cannot recover from. In+-- almost all cases, 'parseM' is the better choice.+--+-- >>> parse "Natural" "12345" :: Natural+-- 12345+--+-- Like 'parseM', this function does not skip over any white space. Use+-- Parsec's primitive 'runParser' or 'runParserT' functions if you don't like+-- this behavior:+--+-- >>> runParser (spaces >> parser) () "Natural" "  1  " :: Either ParseError Natural+-- Right 1++parse :: (Stream input Identity Char, HasParser a) => ErrorContext -> input -> a+parse ctx = either throw id . runParser (parser <* eof) () ctx+++----- Useful HasParser instances ----------------------------------------------++instance HasParser Natural where+  parser = read <$> many1 digit
+ src/Text/Parsec/Class/Orphans.hs view
@@ -0,0 +1,8 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Text.Parsec.Class.Orphans where++import Control.Exception+import Text.Parsec.Error++instance Exception ParseError