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 ({-Show a,-} 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
59 range (c,c') = [c..c']
61 | inRange b ci = fromEnum ci - fromEnum c
62 | otherwise = indexError ci b "Char"
63 inRange (m,n) i = m <= i && i <= n
69 | otherwise = indexError i b "Int"
70 inRange (m,n) i = m <= i && i <= n
72 -- abstract these errors from the relevant index functions so that
73 -- the guts of the function will be small enough to inline.
75 {-# NOINLINE indexError #-}
76 indexError :: Show a => a -> (a,a) -> String -> b
78 = error (showString "Ix{" . showString tp . showString "}.index: Index " .
79 showParen True (showsPrec 0 i) .
80 showString " out of range " $
81 showParen True (showsPrec 0 rng) "")
83 -- Integer instance is in PrelNum
85 ----------------------------------------------------------------------
86 instance Ix Bool where -- as derived
87 range (l,u) = map toEnum [fromEnum l .. fromEnum u]
88 index (l,_) i = fromEnum i - fromEnum l
89 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
91 ----------------------------------------------------------------------
92 instance Ix Ordering where -- as derived
93 range (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 ----------------------------------------------------------------------
100 range ((), ()) = [()]
102 index ((), ()) () = 0
103 {-# INLINE inRange #-}
104 inRange ((), ()) () = True
106 ----------------------------------------------------------------------
107 instance (Ix a, Ix b) => Ix (a, b) where -- as derived
109 range ((l1,l2),(u1,u2)) =
110 [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
113 index ((l1,l2),(u1,u2)) (i1,i2) =
114 index (l1,u1) i1 * rangeSize (l2,u2) + index (l2,u2) i2
116 {- INLINE inRange #-}
117 inRange ((l1,l2),(u1,u2)) (i1,i2) =
118 inRange (l1,u1) i1 && inRange (l2,u2) i2
120 instance (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3) where
121 range ((l1,l2,l3),(u1,u2,u3)) =
122 [(i1,i2,i3) | i1 <- range (l1,u1),
126 index ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
127 index (l3,u3) i3 + rangeSize (l3,u3) * (
128 index (l2,u2) i2 + rangeSize (l2,u2) * (
131 inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
132 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
135 instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where
136 range ((l1,l2,l3,l4),(u1,u2,u3,u4)) =
137 [(i1,i2,i3,i4) | i1 <- range (l1,u1),
142 index ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
143 index (l4,u4) i4 + rangeSize (l4,u4) * (
144 index (l3,u3) i3 + rangeSize (l3,u3) * (
145 index (l2,u2) i2 + rangeSize (l2,u2) * (
148 inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
149 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
150 inRange (l3,u3) i3 && inRange (l4,u4) i4
152 instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
153 range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) =
154 [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1),
160 index ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
161 index (l5,u5) i5 + rangeSize (l5,u5) * (
162 index (l4,u4) i4 + rangeSize (l4,u4) * (
163 index (l3,u3) i3 + rangeSize (l3,u3) * (
164 index (l2,u2) i2 + rangeSize (l2,u2) * (
167 inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
168 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
169 inRange (l3,u3) i3 && inRange (l4,u4) i4 &&
173 %********************************************************
175 \subsection{Size of @Ix@ interval}
177 %********************************************************
179 The @rangeSize@ operator returns the number of elements
180 in the range for an @Ix@ pair:
183 {-# SPECIALISE rangeSize :: (Int,Int) -> Int #-}
184 rangeSize :: (Ix a) => (a,a) -> Int
187 | otherwise = index b h + 1