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 #-} Error ( 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 = error (showString "Ix{Char}.index: Index " .
47 showParen True (showsPrec 0 ci) .
48 showString " out of range " $
49 showParen True (showsPrec 0 b) "")
50 inRange (c,c') ci = fromEnum c <= i && i <= fromEnum c'
57 | otherwise = error (showString "Ix{Int}.index: Index " .
58 showParen True (showsPrec 0 i) .
59 showString " out of range " $
60 showParen True (showsPrec 0 b) "")
61 inRange (m,n) i = m <= i && i <= n
63 -- Integer instance is in PrelNum
65 ----------------------------------------------------------------------
66 instance Ix Bool where -- as derived
67 range (l,u) = map toEnum [fromEnum l .. fromEnum u]
68 index (l,u) i = fromEnum i - fromEnum l
69 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
71 ----------------------------------------------------------------------
72 instance Ix Ordering where -- as derived
73 range (l,u) = map toEnum [fromEnum l .. fromEnum u]
74 index (l,u) i = fromEnum i - fromEnum l
75 inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
77 ----------------------------------------------------------------------
83 {-# INLINE inRange #-}
84 inRange ((), ()) () = True
86 ----------------------------------------------------------------------
87 instance (Ix a, Ix b) => Ix (a, b) where -- as derived
89 range ((l1,l2),(u1,u2)) =
90 [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
93 index ((l1,l2),(u1,u2)) (i1,i2) =
94 index (l1,u1) i1 * rangeSize (l2,u2) + index (l2,u2) i2
96 {-# INLINE inRange #-}
97 inRange ((l1,l2),(u1,u2)) (i1,i2) =
98 inRange (l1,u1) i1 && inRange (l2,u2) i2
100 instance (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3) where
101 range ((l1,l2,l3),(u1,u2,u3)) =
102 [(i1,i2,i3) | i1 <- range (l1,u1),
106 index ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
107 index (l3,u3) i3 + rangeSize (l3,u3) * (
108 index (l2,u2) i2 + rangeSize (l2,u2) * (
111 inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
112 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
115 instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where
116 range ((l1,l2,l3,l4),(u1,u2,u3,u4)) =
117 [(i1,i2,i3,i4) | i1 <- range (l1,u1),
122 index ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
123 index (l4,u4) i4 + rangeSize (l4,u4) * (
124 index (l3,u3) i3 + rangeSize (l3,u3) * (
125 index (l2,u2) i2 + rangeSize (l2,u2) * (
128 inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
129 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
130 inRange (l3,u3) i3 && inRange (l4,u4) i4
132 instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
133 range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) =
134 [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1),
140 index ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
141 index (l5,u5) i5 + rangeSize (l5,u5) * (
142 index (l4,u4) i4 + rangeSize (l4,u4) * (
143 index (l3,u3) i3 + rangeSize (l3,u3) * (
144 index (l2,u2) i2 + rangeSize (l2,u2) * (
147 inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
148 inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
149 inRange (l3,u3) i3 && inRange (l4,u4) i4 &&
153 %********************************************************
155 \subsection{Size of @Ix@ interval}
157 %********************************************************
159 The @rangeSize@ operator returns the number of elements
160 in the range for an @Ix@ pair:
163 rangeSize :: (Ix a) => (a,a) -> Int
166 | otherwise = index b h + 1