#1. The decision about dropping the parentheses depends on which side of the operator we're on. So, here's the new `prettyShow` -- changes in bold:

prettyShow :: (Show a, Num a) => SymbolicManip a -> String -- Show a number or symbol as a bare number or serial prettyShow (Number x) = show x prettyShow (Symbol x) = x prettyShow (BinaryArith op a b) = letpa = maybeLeftParen a oppb = maybeRightParen b oppop = op2str op in pa ++ pop ++ pb prettyShow (UnaryArith opstr a) = opstr ++ "(" ++ show a ++ ")"

Now, for the helper functions. Let's start with handling the left-paren:

maybeLeftParen :: (Show a, Num a) => SymbolicManip a -> Op -> String maybeLeftParen x@(BinaryArith op1 _ _) op | op1 == op && isRightAssociative op = "(" ++ prettyShow x ++ ")" | (opPrio op1) < (opPrio op) = "(" ++ prettyShow x ++ ")" | otherwise = prettyShow x maybeLeftParen x _ = simpleParen x

For this to work, we need to know each operator's priority, and whether the operator is right-associative. These are trivial (the priorities are taken from Haskell's definitions; type `:i (+)` in ghci, for example):

opPrio :: Op -> Int opPrio Plus = 6 opPrio Minus = 6 opPrio Mul = 7 opPrio Div = 7 opPrio Pow = 8 isRightAssociative :: Op -> Bool isRightAssociatove Pow = True isRightAssociative _ = False

Finally, for handling parenthesis to the right of the operator, we have this:

maybeRightParen :: (Show a, Num a) => SymbolicManip a -> Op -> String maybeRightParen x@(BinaryArith op1 _ _) op | prio1 < prio = "(" ++ prettyShow x ++ ")" | prio1 == prio && opIsMinusOrDiv = "(" ++ prettyShow x ++ ")" | otherwise = prettyShow x where prio1 = opPrio op1 prio = opPrio op opIsMinusOrDiv = (op == Minus) || (op == Div) maybeRightParen x _ = simpleParen x

## No comments:

## Post a Comment