Home > OS >  Does a type Int in the rage of 1 <= x <= 255 exist?
Does a type Int in the rage of 1 <= x <= 255 exist?

Time:12-13

I would like to create the following declaration:

data Color = B | W deriving Read

type Cell = (Color, Int) where 1 <= Int <= 255

Is there any solution to this problem ? The type, as it is, accepts any Int but those outside that range shouldn't compile.

CodePudding user response:

Not quite, but if you import Data.Word, there is the type Word8.

This is an "8-bit unsigned integer type", so its values range from 0-255, rather than 1-255 as you wished.

If that is not suitable for you, then the techniques in the answers to the question Noughtmare referred to in their comment are additional things to consider.

CodePudding user response:

1-to-255 is a pretty unusual range. Fairly sure this doesn't exist as such in any library. Are you sure you don't want 0-to-255? In that case, Word8 can be used.

For arbitrary upper bounds (but always 0 as the lower), there is Finite from the finite-typelis package.

In general, what you would typically do to express constraints on a type's values is to introduce a custom newtype wrapper. In doubt, I would actually select Int as the number type – it's way overkill in terms of bit count, but there's not much to be one by selecting something smaller because Haskell boxed values anyway involve an Int-sized pointer. Meanwhile it's still more efficient than Integer.

So,

newtype CellI = CellI { getCellI :: Int -- ^ In range [1,255]
                      }

mkCellI :: Int -> Maybe CellI
mkCellI n
 | n>=1, n<=255  = Just (CellI n)
 | otherwise     = Nothing

Of course, such a wrapper is in some ways awkward. An alternative is to not express the invariant in Haskell at all, but simply use an ordinary Int and then Liquid Haskell for expressing the exact range. This is much more concise for a constraint like range-of-int than if you mess about with pseudo-dependent Haskell.

  • Related