
Hi, On Friday 13 November 2009 21:08:42 Neil Mitchell wrote:
In HLint I have a bracketing module, which has served me well. Please take any ideas you need from it - http://community.haskell.org/~ndm/darcs/hlint/src/HSE/Bracket.hs . In particular, given a fully bracketed expression, I can call transformBracket to transform the expression, not caring about brackets, in a way that guarantees the right brackets are put back. There is also needBracket and isAtom which are very useful. If you call descendBi (transformBracket Just) it will automatically bracket your term as much as is necessary.
Funny, I did the opposite approach the other day (not saying either is better :)); that is: parenthesize everything while building the AST (with a wrapper for App) and then: deparenthesize :: (Data a) => a -> a deparenthesize = everywhereBut isString (mkT goE `extT` goT) where isString x = typeOf x == typeOf (undefined :: String) goE (App (Paren (App e1 e2)) e3) = (App (App e1 e2) e3) goE (Paren (Paren e)) = Paren e goE (InfixApp e1 op'' (Paren (InfixApp e2 op' e3))) | op'' == op' , knownAssociative op'' = InfixApp e1 op'' (InfixApp e2 op' e3) goE (InfixApp (Paren (InfixApp e1 op'' e2)) op' e3) | op'' == op' , knownAssociative op'' = InfixApp (InfixApp e1 op'' e2) op' e3 goE x = x goT (TyApp (TyParen (TyApp t1 t2)) t3) = (TyApp (TyApp t1 t2) t3) -- add rule for function types too goT (TyParen (TyParen t)) = TyParen t goT x = x knownAssociative x = x `elem` [QVarOp (UnQual (Symbol "."))] Though the infix thing doesn't quite work; apparently they still get printed with parens even if there are no parens in the AST? Or the rule just didn't match for some reason... -- Greetings, Daniel