2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[Ix]{Module @Ix@}
8 {-# OPTIONS -fno-implicit-prelude #-}
12 Ix(range, index, inRange),
16 import {-# SOURCE #-} PrelErr ( error )
21 %*********************************************************
23 \subsection{The @Ix@ class}
25 %*********************************************************
28 class (Show a, Ord a) => Ix a where
30 index :: (a,a) -> a -> Int
31 inRange :: (a,a) -> a -> Bool
35 %*********************************************************
37 \subsection{Instances of @Ix@}
39 %*********************************************************
42 instance Ix Char where
43 range (c,c') = [c..c']
45 | inRange b ci = fromEnum ci - fromEnum c
46 | otherwise = indexCharError ci b
47 inRange (c,c') ci = fromEnum c <= i && i <= fromEnum c'
54 | otherwise = indexIntError i b
55 inRange (m,n) i = m <= i && i <= n
57 -- abstract these errors from the relevant index functions so that
58 -- the guts of the function will be small enough to inline.
60 {-# NOINLINE indexCharError #-}
61 indexCharError :: Char -> (Char,Char) -> a
63 = error (showString "Ix{Char}.index: Index " .
64 showParen True (showsPrec 0 ci) .
65 showString " out of range " $
66 showParen True (showsPrec 0 b) "")
68 {-# NOINLINE indexIntError #-}
69 indexIntError :: Int -> (Int,Int) -> a
71 = error (showString "Ix{Int}.index: Index " .
72 showParen True (showsPrec 0 i) .
73 showString " out of range " $
74 showParen True (showsPrec 0 b) "")
76 -- Integer instance is in PrelNum
78 ----------------------------------------------------------------------
79 instance Ix Bool where -- as derived
80 range (l,u) = map toEnum [fromEnum l .. fromEnum u]
81 index (l,u) i = fromEnum i - fromEnum l
82 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
84 ----------------------------------------------------------------------
85 instance Ix Ordering where -- as derived
86 range (l,u) = map toEnum [fromEnum l .. fromEnum u]
87 index (l,u) i = fromEnum i - fromEnum l
88 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
90 ----------------------------------------------------------------------
96 {-# INLINE inRange #-}
97 inRange ((), ()) () = True
99 ----------------------------------------------------------------------
100 instance (Ix a, Ix b) => Ix (a, b) where -- as derived
102 range ((l1,l2),(u1,u2)) =
103 [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
106 index ((l1,l2),(u1,u2)) (i1,i2) =
107 index (l1,u1) i1 * rangeSize (l2,u2) + index (l2,u2) i2
109 {- INLINE inRange #-}
110 inRange ((l1,l2),(u1,u2)) (i1,i2) =
111 inRange (l1,u1) i1 && inRange (l2,u2) i2
113 instance (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3) where
114 range ((l1,l2,l3),(u1,u2,u3)) =
115 [(i1,i2,i3) | i1 <- range (l1,u1),
119 index ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
120 index (l3,u3) i3 + rangeSize (l3,u3) * (
121 index (l2,u2) i2 + rangeSize (l2,u2) * (
124 inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
125 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
128 instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where
129 range ((l1,l2,l3,l4),(u1,u2,u3,u4)) =
130 [(i1,i2,i3,i4) | i1 <- range (l1,u1),
135 index ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
136 index (l4,u4) i4 + rangeSize (l4,u4) * (
137 index (l3,u3) i3 + rangeSize (l3,u3) * (
138 index (l2,u2) i2 + rangeSize (l2,u2) * (
141 inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
142 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
143 inRange (l3,u3) i3 && inRange (l4,u4) i4
145 instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
146 range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) =
147 [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1),
153 index ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
154 index (l5,u5) i5 + rangeSize (l5,u5) * (
155 index (l4,u4) i4 + rangeSize (l4,u4) * (
156 index (l3,u3) i3 + rangeSize (l3,u3) * (
157 index (l2,u2) i2 + rangeSize (l2,u2) * (
160 inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
161 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
162 inRange (l3,u3) i3 && inRange (l4,u4) i4 &&
166 %********************************************************
168 \subsection{Size of @Ix@ interval}
170 %********************************************************
172 The @rangeSize@ operator returns the number of elements
173 in the range for an @Ix@ pair:
176 {-# SPECIALISE rangeSize :: (Int,Int) -> Int #-}
177 rangeSize :: (Ix a) => (a,a) -> Int
180 | otherwise = index b h + 1