    {-# LANGUAGE Rank2Types #-}

    -- Haskell expression parser.  Big hack, but only uses documented APIs so it
    -- should be more robust than the previous hack.
    module Lambdabot.Util.Parser
        ( withParsed
        , prettyPrintInLine
        ) where

    import Data.Generics
    import Language.Haskell.Exts.Simple

    -- |Parse a string as an 'Exp' or a 'Decl', apply the given generic transformation to it,
    -- and re-render it back to text.
    withParsed :: (forall a. (Data a, Eq a) => a -> a) -> String -> String
    withParsed :: (forall a. (Data a, Eq a) => a -> a) -> String -> String
    withParsed forall a. (Data a, Eq a) => a -> a
    _ String
    "" = String
    "Error: expected a Haskell expression or declaration"
    withParsed forall a. (Data a, Eq a) => a -> a
    f String
    s  = case (String -> ParseResult Exp
    parseExp String
    s, String -> ParseResult Decl
    parseDecl String
    s) of
        (ParseOk Exp
    a, ParseResult Decl
    _)          -> Exp -> String
    forall a. Pretty a => a -> String
    prettyPrintInLine (Exp -> String) -> Exp -> String
    forall a b. (a -> b) -> a -> b
    $ Exp -> Exp
    forall a. (Data a, Eq a) => a -> a
    f Exp
    a
        (ParseResult Exp
    _, ParseOk Decl
    a)          -> Decl -> String
    forall a. Pretty a => a -> String
    prettyPrintInLine (Decl -> String) -> Decl -> String
    forall a b. (a -> b) -> a -> b
    $ Decl -> Decl
    forall a. (Data a, Eq a) => a -> a
    f Decl
    a
        (ParseFailed SrcLoc
    l String
    e,  ParseResult Decl
    _)   -> SrcLoc -> String
    forall a. Pretty a => a -> String
    prettyPrint SrcLoc
    l String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Char
    ':' Char -> String -> String
    forall a. a -> [a] -> [a]
    : String
    e

    -- |Render haskell code in a compact format
    prettyPrintInLine :: Pretty a => a -> String
    prettyPrintInLine :: forall a. Pretty a => a -> String
    prettyPrintInLine = PPHsMode -> a -> String
    forall a. Pretty a => PPHsMode -> a -> String
    prettyPrintWithMode (PPHsMode
    defaultMode { layout = PPInLine })