packages feed

PermuteEffects-0.2: ParsecEx.hs

module ParsecEx where

import Control.Replicate
import Control.Permute

import Prelude hiding (id, (.))
import Control.Category

import Data.Traversable
import Control.Applicative hiding (some, many)

import Text.Parsec hiding ((<|>), many, between)


-- | Expect exactly one of each of the 26 letters in the alphabet, in any
-- order, but return them rearranged in sorted order.
alphabet :: String -> Either ParseError String
alphabet = runParser (perms p <* eof) () ""
  where
    p = for ['a'..'z'] (\c -> one *. char c)

-- | Parse the input, collecting the 26 letters from the alphabet in 26
-- buckets.
buckets :: String -> Either ParseError [String]
buckets = runParser (perms p <* eof) () ""
  where
    p = for ['a'..'z'] (\c -> many *. char c)

-- The example from Monad Reader issue 17, page 15
-- http://themonadreader.wordpress.com/2011/01/09/issue-17/
-- A crucial difference is that in our case the individual parsers can have
-- different types.
exampleInterleaveT :: String -> Either ParseError (String, String, Char)
exampleInterleaveT = runParser (perms p <* eof) () ""
  where
    p = (,,) <$> many     *. char 'a'
             <*> atMost 6 *. char 'b'
             <*> one      *. char 'c'