
On Sat, Aug 11, 2007 at 12:06:23AM -0400, David Menendez wrote:
On 8/10/07, Andrew Coppin
wrote: My program needs to make decisions based on a pair of boolean values. Encoding both values as a single algebraic data type means I have to keep "taking it apart" so I can work with it. I'm not sure how much time this wastes...
Incidentally, there is an argument that many (perhaps most) use of Bool should instead be custom datatypes. That is, instead of:
type FooBar = (Bool, Bool)
one should instead do something like
data Foo = Foo | AntiFoo data Bar = Baz | Bo type FooBar = (Foo, Bar)
which makes it clearer what's going on and harder to confuse the two booleans.
Of course, now you have to replace
\(foo, bar) -> if foo then ... else ... with \(foo, bar) -> if foo == Foo then ... else ... or \(foo, bar) -> case foo of { Foo -> ...; Bar -> ... }
Actually, that raises an interesting question. Is there a performance difference between "if foo == Foo ..." and "case Foo of ..."? I think JHC's case-hoisting should be able to transform the former into the latter, but does it?
You don't need to go all the way to JHC[1] for this; GHC's case-of-case transformation is perfectly adequate, as GHC itself will tell you: stefan@stefans:/tmp$ ghc -c -ddump-simpl -O2 X.hs ... X.moo :: X.Ay -> GHC.Base.Int ... X.moo = \ (x_a6D :: X.Ay) -> case x_a6D of wild_Xq { X.Be -> X.lit; X.Ce -> X.lvl } stefan@stefans:/tmp$ cat X.hs module X where data Ay = Be | Ce deriving(Eq) moo x = if x == Be then 2 else (3::Int) stefan@stefans:/tmp$ ghc -c -ddump-simpl-stats -O2 X.hs ==================== FloatOut stats: ==================== 1 Lets floated to top level; 0 Lets floated elsewhere; from 4 Lambda groups ==================== FloatOut stats: ==================== 0 Lets floated to top level; 0 Lets floated elsewhere; from 3 Lambda groups ==================== Grand total simplifier statistics ==================== Total ticks: 46 9 PreInlineUnconditionally 11 PostInlineUnconditionally 6 UnfoldingDone 1 RuleFired 1 ==#->case 9 BetaReduction 2 CaseOfCase <------- 7 KnownBranch 1 CaseMerge 11 SimplifierDone stefan@stefans:/tmp$ Stefan [1] GHC takes 2 hours to run a full two-stage bootstrap complete with the entire standard library. Jhc takes[2] at least 4 hours (I didn't let it finish) to compile just the Prelude. [2] 700MB working set, 384MiB primary store. This makes a difference.