{-# LANGUAGE FlexibleInstances , TypeOperators , GADTs , TypeSynonymInstances , LambdaCase #-} module Parser where import Data.Functor.HFree import Control.Applicative import Control.Monad import Control.Monad.Trans.State data ParserF c a where Symbol :: c -> ParserF c c type Parser c = HFree Alternative (ParserF c) symbol :: c -> Parser c c symbol = liftFree . Symbol parseF :: Eq c => ParserF c :~> StateT [c] Maybe parseF (Symbol c) = StateT $ \case (a:as) | c == a -> Just (a, as) _ -> Nothing parse :: Eq c => Parser c a -> [c] -> Maybe a parse p = fmap fst . mfilter (null . snd) . runStateT (rightAdjunct parseF p) parenDepth :: Parser Char Int parenDepth = maximum . (0:) <$> many (succ <$> (symbol '(' *> parenDepth <* symbol ')')) maxDepth :: String -> Maybe Int maxDepth = parse parenDepth