2 % (c) The AQUA Project, Glasgow University, 1994-1999
5 \section[Ix]{Module @Ix@}
8 {-# OPTIONS -fno-implicit-prelude #-}
13 ( range -- :: (Ix a) => (a,a) -> [a]
14 , index -- :: (Ix a) => (a,a) -> a -> Int
15 , inRange -- :: (Ix a) => (a,a) -> a -> Bool
17 , rangeSize -- :: (Ix a) => (a,a) -> Int
26 -- (Ix a, Ix b) => Ix (a, b)
29 -- Implementation checked wrt. Haskell 98 lib report, 1/99.
32 import {-# SOURCE #-} PrelErr ( error )
37 %*********************************************************
39 \subsection{The @Ix@ class}
41 %*********************************************************
44 class (Ord a) => Ix a where
46 index :: (a,a) -> a -> Int
47 inRange :: (a,a) -> a -> Bool
51 %*********************************************************
53 \subsection{Instances of @Ix@}
55 %*********************************************************
58 instance Ix Char where
63 | inRange b i = fromEnum i - fromEnum m
64 | otherwise = indexError i b "Char"
65 inRange (m,n) i = m <= i && i <= n
73 | otherwise = indexError i b "Int"
74 inRange (m,n) i = m <= i && i <= n
76 -- abstract these errors from the relevant index functions so that
77 -- the guts of the function will be small enough to inline.
79 {-# NOINLINE indexError #-}
80 indexError :: Show a => a -> (a,a) -> String -> b
82 = error (showString "Ix{" . showString tp . showString "}.index: Index " .
83 showParen True (showsPrec 0 i) .
84 showString " out of range " $
85 showParen True (showsPrec 0 rng) "")
87 -- Integer instance is in PrelNum
89 ----------------------------------------------------------------------
90 instance Ix Bool where -- as derived
92 | l <= u = map toEnum [fromEnum l .. fromEnum u]
94 index (l,_) i = fromEnum i - fromEnum l
95 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
97 ----------------------------------------------------------------------
98 instance Ix Ordering where -- as derived
100 | l <= u = map toEnum [fromEnum l .. fromEnum u]
102 index (l,_) i = fromEnum i - fromEnum l
103 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
105 ----------------------------------------------------------------------
108 range ((), ()) = [()]
110 index ((), ()) () = 0
111 {-# INLINE inRange #-}
112 inRange ((), ()) () = True
114 ----------------------------------------------------------------------
115 instance (Ix a, Ix b) => Ix (a, b) where -- as derived
117 range ((l1,l2),(u1,u2)) =
118 [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
121 index ((l1,l2),(u1,u2)) (i1,i2) =
122 index (l1,u1) i1 * rangeSize (l2,u2) + index (l2,u2) i2
124 {- INLINE inRange #-}
125 inRange ((l1,l2),(u1,u2)) (i1,i2) =
126 inRange (l1,u1) i1 && inRange (l2,u2) i2
128 instance (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3) where
129 range ((l1,l2,l3),(u1,u2,u3)) =
130 [(i1,i2,i3) | i1 <- range (l1,u1),
134 index ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
135 index (l3,u3) i3 + rangeSize (l3,u3) * (
136 index (l2,u2) i2 + rangeSize (l2,u2) * (
139 inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
140 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
143 instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where
144 range ((l1,l2,l3,l4),(u1,u2,u3,u4)) =
145 [(i1,i2,i3,i4) | i1 <- range (l1,u1),
150 index ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
151 index (l4,u4) i4 + rangeSize (l4,u4) * (
152 index (l3,u3) i3 + rangeSize (l3,u3) * (
153 index (l2,u2) i2 + rangeSize (l2,u2) * (
156 inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
157 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
158 inRange (l3,u3) i3 && inRange (l4,u4) i4
160 instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
161 range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) =
162 [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1),
168 index ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
169 index (l5,u5) i5 + rangeSize (l5,u5) * (
170 index (l4,u4) i4 + rangeSize (l4,u4) * (
171 index (l3,u3) i3 + rangeSize (l3,u3) * (
172 index (l2,u2) i2 + rangeSize (l2,u2) * (
175 inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
176 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
177 inRange (l3,u3) i3 && inRange (l4,u4) i4 &&
181 %********************************************************
183 \subsection{Size of @Ix@ interval}
185 %********************************************************
187 The @rangeSize@ operator returns the number of elements
188 in the range for an @Ix@ pair:
191 {-# SPECIALISE rangeSize :: (Int,Int) -> Int #-}
192 rangeSize :: (Ix a) => (a,a) -> Int
194 | l > h || isnull (range b) = 0
195 | otherwise = index b h + 1