Data.Ix

haskell2010-1.1.2.0: Compatibility with Haskell 2010

Safe Haskell | Safe
Language | Haskell2010

Data.Ix

Contents

- The `Ix` class
- Deriving Instances of `Ix`

Synopsis

- class Ord a => Ix a where
  - range :: (a, a) -> [a]
  - index :: (a, a) -> a -> Int
  - inRange :: (a, a) -> a -> Bool
  - rangeSize :: (a, a) -> Int

# The `Ix` class

class Ord a => Ix a where Source

The `Ix` class is used to map a contiguous subrange of values in a type onto integers. It is used primarily for array indexing (see the array package).

The first argument `(l,u)` of each of these operations is a pair specifying the lower and upper bounds of a contiguous subrange of values.

An implementation is entitled to assume the following laws about these operations:

- ``inRange` (l,u) i == `elem` i (`range` (l,u))` ``
- ``range` (l,u) `!!` `index` (l,u) i == i`, when ``inRange` (l,u) i`
- ``map` (`index` (l,u)) (`range` (l,u))) == [0..`rangeSize` (l,u)-1]` ``
- ``rangeSize` (l,u) == `length` (`range` (l,u))` ``

Minimal complete instance: `range`, `index` and `inRange`.

Minimal complete definition

range, inRange

Methods

range :: (a, a) -> [a] Source

The list of values in the subrange defined by a bounding pair.

index :: (a, a) -> a -> Int Source

The position of a subscript in the subrange.

inRange :: (a, a) -> a -> Bool Source

Returns `True` the given subscript lies in the range defined the bounding pair.

rangeSize :: (a, a) -> Int Source

The size of the subrange defined by a bounding pair.

Instances

Ix Bool |
Ix Char |
Ix Int |
Ix Int8 |
Ix Int16 |
Ix Int32 |
Ix Int64 |
Ix Integer |
Ix Ordering |
Ix Word |
Ix Word8 |
Ix Word16 |
Ix Word32 |
Ix Word64 |
Ix () |
Ix IOMode |
Ix SeekMode |
Ix GeneralCategory |
(Ix a, Ix b) => Ix (a, b) |
(Ix a1, Ix a2, Ix a3) => Ix (a1, a2, a3) |
(Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1, a2, a3, a4) |
(Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1, a2, a3, a4, a5) |

# Deriving Instances of `Ix`

It is possible to derive an instance of `Ix` automatically, using a `deriving` clause on a `data` declaration. Such derived instance declarations for the class `Ix` are only possible for enumerations (i.e. datatypes having only nullary constructors) and single-constructor datatypes, whose constituent types are instances of `Ix`. A Haskell implementation must provide `Ix` instances for tuples up to at least size 15.

For an enumeration, the nullary constructors are assumed to be numbered left-to-right with the indices being 0 to n-1 inclusive. This is the same numbering defined by the `Enum` class. For example, given the datatype:

    data Colour = Red | Orange | Yellow | Green | Blue | Indigo | Violet

we would have:

    range   (Yellow,Blue)        ==  [Yellow,Green,Blue]
    index   (Yellow,Blue) Green  ==  1
    inRange (Yellow,Blue) Red    ==  False

For single-constructor datatypes, the derived instance declarations are as shown for tuples:

    instance  (Ix a, Ix b)  => Ix (a,b) where
            range ((l,l'),(u,u'))
                    = [(i,i') | i <- range (l,u), i' <- range (l',u')]
            index ((l,l'),(u,u')) (i,i')
                    =  index (l,u) i * rangeSize (l',u') + index (l',u') i'
            inRange ((l,l'),(u,u')) (i,i')
                    = inRange (l,u) i && inRange (l',u') i'

    -- Instances for other tuples are obtained from this scheme:
    --
    --  instance  (Ix a1, Ix a2, ... , Ix ak) => Ix (a1,a2,...,ak)  where
    --      range ((l1,l2,...,lk),(u1,u2,...,uk)) =
    --          [(i1,i2,...,ik) | i1 <- range (l1,u1),
    --                            i2 <- range (l2,u2),
    --                            ...
    --                            ik <- range (lk,uk)]
    --
    --      index ((l1,l2,...,lk),(u1,u2,...,uk)) (i1,i2,...,ik) =
    --        index (lk,uk) ik + rangeSize (lk,uk) * (
    --         index (lk-1,uk-1) ik-1 + rangeSize (lk-1,uk-1) * (
    --          ...
    --           index (l1,u1)))
    --
    --      inRange ((l1,l2,...lk),(u1,u2,...,uk)) (i1,i2,...,ik) =
    --          inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
    --              ... && inRange (lk,uk) ik