Copyright | © 2017–2018 Mark Karpov |
---|---|

License | BSD 3 clause |

Maintainer | Mark Karpov <markkarpov92@gmail.com> |

Stability | experimental |

Portability | portable |

Safe Haskell | Safe |

Language | Haskell2010 |

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`

, 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*

- data Permutation m a
- runPermutation :: (Alternative m, Monad m) => Permutation m a -> m a
- intercalateEffect :: (Alternative m, Monad 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 a Source #

An `Applicative`

wrapper-type for constructing permutation parsers.

Functor m => Functor (Permutation m) Source # | |

Alternative m => Applicative (Permutation m) Source # | |

## Permutation evaluators

:: (Alternative m, Monad 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.

:: (Alternative m, Monad m) | |

=> m b | Effect to be intercalated between permutation components |

-> 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 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.

## Permutation constructors

:: Alternative m | |

=> m a | Permutation component |

-> Permutation m a |

"Lifts" a parser to a permutation parser.

toPermutationWithDefault Source #

:: 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.