How can natural numbers be represented to offer constant time addition?
data-structures, haskell, math
Solution
As far as I know, Idris (a dependently-typed purely functional language which is very close to Haskell) deals with this in a quite straightforward way. Compiler is aware of `Nat`s and `Fin`s (upper-bounded `Nat`s) and replaces them with machine integer types and operations whenever possible, so the resulting code is pretty effective. However, that's not true for custom types (even isomorphic ones) as well as for compilation stage (there were some code samples using `Nat`s for type checking which resulted in exponential growth in compile-time, I can provide them if needed).
In case of Haskell, I think a similar compiler extension may be implemented. Another possibility is to make TH macros which would transform the code. Of course, both of options aren't easy.
Problem
Cirdec's answer to a largely unrelated question made me wonder how best to represent natural numbers with constant-time addition, subtraction by one, and testing for zero. Why Peano arithmetic isn't good enough: Suppose we use ``` data Nat = Z | S Nat ``` Then we can write ``` Z + n = n S m + n = S(m+n) ``` We can calculate `m+n` in O(1) time by placing `m-r` debits (for some constant `r`), one on each `S` constructor added onto `n`. To get O(1) `isZero`, we need to be sure to have at most `p` debits per `S` constructor, for some constant `p`. This works great if we calculate `a + (b + (c+...))`, but it falls apart if we calculate `((...+b)+c)+d`. The trouble is that the debits stack up on the front end. One option The easy way out is to just use catenable lists, such as the ones Okasaki describes, directly. There are two problems: O(n) space is not really ideal. It's not entirely clear (at least to me) that the complexity of bootstrapped queues is necessary when we don't care about order the way we would for lists.