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'