    {- |
    Implementations of 'Ix' methods in terms of 'Enum' methods.

    For a type @T@ of class 'Enum' you can easily define an 'Ix' instance
    by copying the following code into your module:

    >import qualified Data.Ix.Enum as IxEnum
    >
    >instance Ix T where
    >   range           = IxEnum.range
    >   index           = IxEnum.index
    >   inRange         = IxEnum.inRange
    >   rangeSize       = IxEnum.rangeSize
    >   unsafeIndex     = IxEnum.unsafeIndex
    >   unsafeRangeSize = IxEnum.unsafeRangeSize

    -}
    module Data.Ix.Enum where

    {-# INLINE range #-}
    {-# INLINE index #-}
    {-# INLINE unsafeIndex #-}
    {-# INLINE inRange #-}
    {-# INLINE rangeSize #-}
    {-# INLINE unsafeRangeSize #-}

    range :: Enum a => (a, a) -> [a]
    index :: Enum a => (a, a) -> a -> Int
    unsafeIndex :: Enum a => (a, a) -> a -> Int
    inRange :: Enum a => (a, a) -> a -> Bool
    rangeSize :: Enum a => (a, a) -> Int
    unsafeRangeSize :: Enum a => (a, a) -> Int

    range :: forall a. Enum a => (a, a) -> [a]
    range (a
    l,a
    r) = (Int -> a) -> [Int] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> a
    forall a. Enum a => Int -> a
    toEnum ([Int] -> [a]) -> [Int] -> [a]
    forall a b. (a -> b) -> a -> b
    $ (Int, Int) -> [Int]
    forall a. Enum a => (a, a) -> [a]
    range (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    l, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    r)
    index :: forall a. Enum a => (a, a) -> a -> Int
    index (a
    l,a
    r) a
    i = (Int, Int) -> Int -> Int
    forall a. Enum a => (a, a) -> a -> Int
    index (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    l, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    r) (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    i)
    unsafeIndex :: forall a. Enum a => (a, a) -> a -> Int
    unsafeIndex (a
    l,a
    r) a
    i = (Int, Int) -> Int -> Int
    forall a. Enum a => (a, a) -> a -> Int
    unsafeIndex (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    l, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    r) (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    i)
    inRange :: forall a. Enum a => (a, a) -> a -> Bool
    inRange (a
    l,a
    r) a
    i = (Int, Int) -> Int -> Bool
    forall a. Enum a => (a, a) -> a -> Bool
    inRange (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    l, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    r) (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    i)
    rangeSize :: forall a. Enum a => (a, a) -> Int
    rangeSize (a
    l,a
    r) = (Int, Int) -> Int
    forall a. Enum a => (a, a) -> Int
    rangeSize (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    l, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    r)
    unsafeRangeSize :: forall a. Enum a => (a, a) -> Int
    unsafeRangeSize (a
    l,a
    r) = (Int, Int) -> Int
    forall a. Enum a => (a, a) -> Int
    unsafeRangeSize (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    l, a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    r)