Control.Applicative.Permutations

parser-combinators-1.3.0: Lightweight package providing commonly useful parser combinators

Copyright | © 2017–present Alex Washburn
License | BSD 3 clause
Maintainer | Mark Karpov <markkarpov92@gmail.com>
Stability | experimental
Portability | portable
Safe Haskell | Safe-Inferred
Language | Haskell2010

Control.Applicative.Permutations

Contents

- Permutation type
- Permutation evaluators
- Permutation constructors

Description

This module is a generalization of the package `parsec-permutation` authored by Samuel Hoffstaetter:

https://hackage.haskell.org/package/parsec-permutation

This module also takes inspiration from the algorithm is described in: Parsing Permutation Phrases, by Arthur Baars, Andres Löh and Doaitse Swierstra. Published as a functional pearl at the Haskell Workshop 2001:

https://www.cs.ox.ac.uk/jeremy.gibbons/wg21/meeting56/loeh-paper.pdf

From these two works we derive a flexible and general method for parsing permutations over an `Applicative` structure. Quite useful in conjunction with "Free" constructions of `Applicative`s, `Monad`s, etc.

Other permutation parsing libraries tend towards using special "almost applicative" combinators for construction which denies the library user the ability to lift and unlift permutation parsing into any `Applicative` computational context. We redefine these combinators as convenience operators here alongside the equivalent `Applicative` instance.

For example, suppose we want to parse a permutation of: an optional string of `a`'s, the character `b` and an optional `c`. Using a standard parsing library combinator `char` (e.g. `ReadP`) this can be described using the `Applicative` instance by:

    test = runPermutation $
             (,,) <$> toPermutationWithDefault ""  (some (char 'a'))
                  <*> toPermutation (char 'b')
                  <*> toPermutationWithDefault '_' (char 'c')

Since: 0.2.0

Synopsis

- data Permutation (m :: Type -> Type) a
- runPermutation :: Alternative m => Permutation m a -> m a
- intercalateEffect :: Alternative m => m b -> Permutation m a -> m a
- toPermutation :: Alternative m => m a -> Permutation m a
- toPermutationWithDefault :: Alternative m => a -> m a -> Permutation m a

## Permutation type

data Permutation (m :: Type -> Type) a #

An `Applicative` wrapper-type for constructing permutation parsers.

#### Instances

Instances details

Functor m => Applicative (Permutation m) # |
Instance details Defined in Control.Applicative.Permutations Methods pure :: a -> Permutation m a # (<*>) :: Permutation m (a -> b) -> Permutation m a -> Permutation m b # liftA2 :: (a -> b -> c) -> Permutation m a -> Permutation m b -> Permutation m c # (*>) :: Permutation m a -> Permutation m b -> Permutation m b # (<*) :: Permutation m a -> Permutation m b -> Permutation m a #
Functor m => Functor (Permutation m) # |
Instance details Defined in Control.Applicative.Permutations Methods fmap :: (a -> b) -> Permutation m a -> Permutation m b # (<$) :: a -> Permutation m b -> Permutation m a #

## Permutation evaluators

runPermutation #

Arguments

:: Alternative m |
=> Permutation m a | Permutation specification
-> m a | Resulting base monad capable of handling the permutation

"Unlifts" a permutation parser into a parser to be evaluated.

intercalateEffect #

Arguments

:: Alternative m |
=> m b | Effect to be intercalated between permutation components
-> Permutation m a | Permutation specification
-> m a | Resulting base applicative capable of handling the permutation

"Unlifts" a permutation parser into a parser to be evaluated with an intercalated effect. Useful for separators between permutation elements.

For example, suppose that similar to above we want to parse a permutation of: an optional string of `a`'s, the character `b` and an optional `c`. However, we also want each element of the permutation to be separated by a colon. Using a standard parsing library combinator `char`, this can be described using the `Applicative` instance by:

    test = intercalateEffect (char ':') $
             (,,) <$> toPermutationWithDefault "" (some (char 'a'))
                  <*> toPermutation (char 'b')
                  <*> toPermutationWithDefault '_' (char 'c')

This will accept strings such as: "a:b:c", "b:c:a", "b:aa", "b", etc.

Note that the effect is intercalated between permutation components and that:

- There is never an effect parsed preceeding the first component of the permutation.
- There is never an effect parsed following the last component of the permutation.
- No effects are intercalated between missing components with a default value.
- If an effect is encountered after a component, another component must immediately follow the effect.

## Permutation constructors

toPermutation #

Arguments

:: Alternative m |
=> m a | Permutation component
-> Permutation m a |

"Lifts" a parser to a permutation parser.

toPermutationWithDefault #

Arguments

:: Alternative m |
=> a | Default Value
-> m a | Permutation component
-> Permutation m a |

"Lifts" a parser with a default value to a permutation parser.

If no permutation containing the supplied parser can be parsed from the input, then the supplied default value is returned in lieu of a parse result.