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

Daniel Fischer daniel.is.fischer at web.de
Fri May 8 16:30:25 EDT 2009


Am Freitag 08 Mai 2009 20:22:23 schrieb aditya siram:
> 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

I'm sure there are several implementations of a natural number datatype on Hackage (e.g. 
lazy Peano Numbers).
And of course there are Word, Word32, Word64 (from Data.Word), but they wrap on underflow.

Another option is to define an opaque type yourself:

module Natural (Natural, mkNatural, maybeNatural) where

newtype Natural = N Integer
      deriving (Eq, Ord, Show)

mkNatural :: Integer -> Natural
mkNatural n
    | n < 0    = error "Naturals must be non-negative"
    | otherwise = N n

maybeNatural :: Integer -> Maybe Natural
maybeNatural n
    | n < 0    = Nothing
    | otherwise = N n

instance Num Natural where
    (N m) + (N n) = N (n+m)
    (N m) - (N n) = mkNatural (m-n)
    (N m) * (N n) = N (m*n)
    abs = id
    signum (N n) = if n == 0 then (N 0) else (N 1)
    negate n = error "Can't negate Naturals"
    fromInteger = mkNatural

doesn't give you hard compile-time guarantees, but at least you get an error and not a 
hard-to-find bug.


More information about the Beginners mailing list