
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

| 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? In the following definition, one is not allowed to: instance Functor (Either a) where fmap f (Left a) = Left a fmap f (Right b) = Right (f b) The first line cannot be written as: fmap f x@(Left a) = x Because it does not type check! /Koen.

On Friday 07 December 2001 3:09 pm, Simon Marlow wrote:
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?
In this particular case they do, but sometimes this isn't so. IE in.. case <expression1> x@<pattern> -> <expression2> the x has the same type as <expression1>, which isn't necessarily the same as would be inferred using.. x=<pattern> (here the pattern is really an expression of course) A long long time ago I griped about this in a thread the main haskell.org mailing list (called "Pattern match success changes types" IIRC). IMHO variables bound using 'as patterns' like.. x@<pattern> -> <expression> should be re-typed as if they had been written.. <pattern> -> let x=<pattern> in <expression> in order to make sharing possible. I don't think anybody agrees with me though :-) Regards -- Adrian Hey
participants (3)
-
Adrian Hey
-
Koen Claessen
-
Simon Marlow