[Haskell-beginners] A Quantity Type - Integer without the Negative #'s

Alexander Dunlap alexander.dunlap at gmail.com
Fri May 8 18:36:55 EDT 2009


On Fri, May 8, 2009 at 11:22 AM, aditya siram <aditya.siram at gmail.com> wrote:
> Hi all,
> Is there a datatype in Haskell that can be used to represent only quantities
>>= 0?  I got bitten by a bug because I forgot to reject an amount that was
> below zero after applying a decrementing operator. A simple unit test would
> have caught this, but I was wondering if there was some way of getting the
> type system to ensure this.
>
> thanks ...
> -deech

There are a number of ways of doing this, none of them entirely
satisfactory. The essential problem is that subtraction becomes a
partial function; i.e. if you try to subtract a and b, there's no way
for the compiler to statically know if that's going to be nonnegative
or not.

One option would be to make a newtype of Integer, define (+), (*),
etc. as with regular integers, define abs = id, negate = undefined.
Then you can either make (-) a partial function (as in

(NonNeg x) - (NonNeg y) = case x - y of
  z | z >= 0 -> z
     | otherwise -> undefined

) or leave subtraction undefined and make a maybeSubtract function
that returns a Maybe value based on whether or not the result would be
positive or negative. A third option would be to just take the
absolute value of the result of a subtraction, although this should be
used ONLY in situations where it is appropriate because usually you
want to distinguish between x and -x.

You could also use Peano numerals, but I don't think that those are
very efficient. That's where you define

data Nat = Zero | Succ Nat

and so 3 :: Nat = Succ (Succ (Succ Zero)) etc.

Hope that's of some help to you.

Alex


More information about the Beginners mailing list