Math from scratch in Haskell: zero and one

I’ve been following a set of posts written by Eric Lippert where he is implementing arbitrary size Naturals and the corresponding arithmetic in C#. As I follow along I’m writing an implementation in Haskell (one that I hope is idiomatic to Haskell).

In part one and part two of the series he develops a representation of Naturals and exposes two public members: Zero and One. Read those two posts to understand his implementation.

Here is my implementation

module Natural (Natural, zero, one) where

data Bit = ZeroBit | OneBit

data Natural = Zero | Nat Bit Natural

zero = Zero
one = Nat OneBit Zero

-- Creates a natural number. Keeps the invariant that
-- Naturals always end with Zero and never end with
-- a ZeroBit followed by Zero
createNatural :: Natural -> Bit -> Natural
createNatural Zero ZeroBit = Zero
createNatural Zero OneBit = one
createNatural n b = Nat b n


On line 1 we expose the new type and two public values: zero and one.

I define two new types: Bit and Natural. The definition of Bit is straightforward. I simply define two constructors: ZeroBit and OneBit. Likewise the definition of Natural follows directly from the recursive definition given by Eric. I can construct a Natural by using the Zero constructor or by using the Nat constructor (which adds a new least significant bit onto an existing Natural).

Like Eric’s implementation I use a helper function to maintain the invariant he mentions that a Natural never ends in a ZeroBit followed by a Zero.

The definitions of zero and one are straightforward as well. That’s it.

I’ll continue to add posts that follow Eric’s posts. The next post will show how to implement addition.