Haskell newbie here.
I wrote an evaluator for a minimal assembly-like language.
Now, I want to extend that language to support some syntactic sugar which,
A (simpler) option is to add a type to your AST, to distinguish Core from Extended:
data Core = Core
data Extended = Extended
data Expr t
= Add (Expr t) (Expr t)
| Mult (Expr t) (Expr t)
| Const Int
| Sugar t (Expr t) (Expr t)
An expression is either Core or Extended: the compiler will ensure that it contains only sub-expressions of the same type.
The function signatures in your original module would need to use Expr Core (instead of just Expr)
A Desugar function would have the following type signature:
Desugar :: Expr Extended -> Expr Core
You may also be interested in the more sophisticated approach described in the paper 'Trees that grow'.