Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A more generic version allows you to parameterize based on the bound:

    newtype BoundedInt b = BoundedInt Int

    class Bound b where
      boundRange :: t b -> (Int, Int)

    fromBounded :: BoundedInt b -> Int
    fromBounded (BoundedInt x) = x

    toBounded :: Bound b => Int -> BoundedInt b
    toBounded x =
      let result = BoundedInt x
	  (minb, maxb) = boundRange result
      in if minb <= result && result <= maxb
	 then result
	 else error $ "Out of range: " ++ show x

    instance Bound b => Num (BoundedInt b) where
      abs = toBounded . abs . fromBounded
      negate = toBounded . negate . fromBounded
      signum = toBounded . signum . fromBounded
      x + y = toBounded (fromBounded x + fromBounded y)
      x - y = toBounded (fromBounded x - fromBounded y)
      x * y = toBounded (fromBounded x * fromBounded y)
      fromInteger = toBounded . fromInteger
This assumes you want exceptions for overflow. Nowadays, you can put numbers in the type system, obviating the need for a "Bound" class, but I'm not familiar with it yet. The implementation above will also silently overflow given large enough bounds.


Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: