├── .gitignore ├── LICENSE ├── Setup.hs ├── src └── Control │ └── Monad │ └── Yoctoparsec.hs └── yoctoparsec.cabal /.gitignore: -------------------------------------------------------------------------------- 1 | dist-newstyle/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 mniip 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /src/Control/Monad/Yoctoparsec.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Control.Monad.Yoctoparsec 4 | -- Copyright : (C) 2016 mniip 5 | -- License : MIT 6 | -- Maintainer : mniip 7 | -- Stability : experimental 8 | -- Portability : portable 9 | -------------------------------------------------------------------------------- 10 | module Control.Monad.Yoctoparsec 11 | ( 12 | Parser, 13 | token, 14 | parseStream, 15 | parseString 16 | ) 17 | where 18 | 19 | import Data.List 20 | import Control.Applicative 21 | import Control.Monad 22 | import Control.Monad.State 23 | import Control.Monad.Trans.Free 24 | 25 | -- | A @Parser b t a@ is a parser that consumes a stream of @t@ tokens and as a 26 | -- result yields a value of type @a@, while operating under the @b@ 27 | -- non-determinism monad. For most purposes @b@ should be a 'MonadPlus'. Useful 28 | -- examples include @[]@ if you want backtracking, 'Maybe' if you want no 29 | -- backtracking, @'StateT' []@ if you want to maintain a state that is 30 | -- automatically reverted when backtracking, and so on. 'hoistFreeT' can be used 31 | -- to change the backtracking monad. 32 | -- 33 | -- 'FreeT' provides us with instances for 'Functor', 'Applicative', 'Monad', 34 | -- 'Alternative' and 'MonadPlus'. 35 | type Parser b t a = FreeT ((->) t) b a 36 | 37 | -- | A trivial parser that consumes a single token and yields it. Other parsers 38 | -- can be derived from this one using methods of the aforementioned typeclasses. 39 | -- For example, 40 | -- @ 41 | -- char x = mfilter (== x) token 42 | -- @ 43 | token :: Applicative b => Parser b t t 44 | token = FreeT . pure . Free $ FreeT . pure . Pure 45 | 46 | -- | Apply a parser to a stream given a function that obtains the next character 47 | -- from the stream within the same non-determinism monad. 48 | parseStream :: Monad b => (s -> b (t, s)) -> Parser b t a -> s -> b (a, s) 49 | parseStream next = runStateT . iterTM (StateT next >>=) 50 | 51 | -- | Parse a string. When the end of the string is encountered, 'empty' is 52 | -- yielded into the non-determinism monad. 53 | parseString :: MonadPlus b => Parser b t a -> [t] -> b (a, [t]) 54 | parseString = parseStream (maybe empty pure . uncons) 55 | -------------------------------------------------------------------------------- /yoctoparsec.cabal: -------------------------------------------------------------------------------- 1 | name: yoctoparsec 2 | version: 0.1.0.0 3 | synopsis: A truly tiny monadic parsing library 4 | description: A monadic parsing library making use of the free monad 5 | transformer. All instances are provided by the FreeT monad. 6 | homepage: https://github.com/mniip/yoctoparsec 7 | license: MIT 8 | license-file: LICENSE 9 | author: mniip 10 | maintainer: mniip@mniip.com 11 | copyright: (C) 2016 mniip 12 | category: Parsing 13 | build-type: Simple 14 | cabal-version: >=1.10 15 | 16 | library 17 | exposed-modules: Control.Monad.Yoctoparsec 18 | build-depends: base >= 4.8 && < 4.15, free >= 4.0, mtl >= 2.0.0.0 19 | hs-source-dirs: src 20 | default-language: Haskell2010 21 | --------------------------------------------------------------------------------