Skip to content

Document differences between Ix's inRange and UniformRange's isInRange #178

@RyanGlScott

Description

@RyanGlScott

When upgrading a package of mine to support random-1.3.0, I needed to add an implementation of isInRange to a UniformRange instance in order to make it typecheck. There already existed an Ix instance for the same type, and the Ix class offers a very similar-looking inRange method. As such, I was tempted to define isInRange in the UniformRange instance like so:

instance UniformRange T where
  ...
  isInRange = inRange

I later discovered that this is incorrect! This is because UniformRange's isInRange requires the ranges to be symmetric, i.e.,

isInRange (lo, hi) x == isInRange (hi, lo) x

But this law does not necessarily hold for Ix's inRange. This can be seen in the UniformRange and Ix instances for Int:

λ> isInRange (1, 0 :: Int) 0 -- UniformRange
True
λ> inRange (1, 0 :: Int) 0 -- Ix
False

There might be other differences between isInRange and inRange that I am not aware of, but this was one of the more prominent ones that I discovered. I worry that others may fall into the same pitfall. Would you be willing to document these differences in the Haddocks for isInRange to make them more obvious?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions