
I sometimes wonder just how far I should go in obfuscating code by manually implementing trivial optimisations that should (IMHO) be implemented by the compiler, but may not be.
So I have a couple of specific questions..
The first is.. Does the compiler keep a unique copy of expressions which consist of just a single zero arity constructor (eg. [],True,Nothing..) as a CAF which is referenced each time the constructor appears in an expression, or does it duplicate the constructor (expression) each time it's used. Maybe I should define my own CAF at the top level and use it instead? (or perhaps they're unboxed somehow?)
Nullary constructors are represented by a single static constructor, they are never built dynamically. So feel free to write [] wherever you like - it has the same cost as a variable.
The second is.. If, following pattern matching, the matched pattern appears in an expression, is it shared or duplicated.. e.g. (a:as) -> f (a:as) Maybe I should write something like this.. x@(a:as) -> f x (I know that sometimes the type checker won't allow you to do this)
Yes, GHC will common these up (with -O). I'm not sure I understand the point about the type checker not letting you do this yourself, though: surely x and (a:as) have the same type? Cheers, Simon