-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
Description
Currently we have
fromInteger n0
| n0 >= 0 = go n0
| otherwise = neg $ go (- n0)
where
go 0 = zer
go 1 = one
go 2 = two
go n | even n = two `mul` fromInteger (n `Prelude.div` 2)
go n = one `add` fromInteger (n - 1)So fromInteger 15 evaluates as
one `add` (two `mul` (one `add` (two `mul` (one `add` two))))(i.e. 1 + (2 * (1 + 2 * (1 + 2)))) but it would make more sense to evaluate it as
(two `mul` (two `mul` (two `mul` two))) `sub` one(i.e. 2 * (2 * (2 * 2)) - 1).
We assume that negation is a cheap operation (which it is in all of our fields).
We can implement such an optimization by looking at the last two digits of an Integer on each step. If it's 15, then make it 16, recurse and subtract one from the result. If it's 17, then make it 16, recurse and add one to the result. Turn 25 into 24 and turn 27 into 28. Etc.
Not something very important, just shower thoughts.