af16fda1f79e4b27fdc9fe6d2371ebc700850d48
[ghc-hetmet.git] / ghc / lib / std / Ix.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1996
3 %
4
5 \section[Ix]{Module @Ix@}
6
7 \begin{code}
8 {-# OPTIONS -fno-implicit-prelude #-}
9
10 module Ix 
11     (
12         Ix(range, index, inRange),
13         rangeSize
14     ) where
15
16 import {-# SOURCE #-} PrelErr ( error )
17 import PrelTup
18 import PrelBase
19 \end{code}
20
21 %*********************************************************
22 %*                                                      *
23 \subsection{The @Ix@ class}
24 %*                                                      *
25 %*********************************************************
26
27 \begin{code}
28 class  (Show a, Ord a) => Ix a  where
29     range               :: (a,a) -> [a]
30     index               :: (a,a) -> a -> Int
31     inRange             :: (a,a) -> a -> Bool
32 \end{code}
33
34
35 %*********************************************************
36 %*                                                      *
37 \subsection{Instances of @Ix@}
38 %*                                                      *
39 %*********************************************************
40
41 \begin{code}
42 instance  Ix Char  where
43     range (c,c')        =  [c..c']
44     index b@(c,c') ci
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'
51                            where i = fromEnum ci
52
53 instance  Ix Int  where
54     range (m,n)         =  [m..n]
55     index b@(m,n) i
56         | inRange b i   =  i - m
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
62
63 -- Integer instance is in PrelNum
64
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
70
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
76
77 ----------------------------------------------------------------------
78 instance Ix () where
79     {-# INLINE range #-}
80     range   ((), ())    = [()]
81     {-# INLINE index #-}
82     index   ((), ()) () = 0
83     {-# INLINE inRange #-}
84     inRange ((), ()) () = True
85
86 ----------------------------------------------------------------------
87 instance (Ix a, Ix b) => Ix (a, b) where -- as derived
88     {-# INLINE range #-}
89     range ((l1,l2),(u1,u2)) =
90       [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
91
92     {-# INLINE index #-}
93     index ((l1,l2),(u1,u2)) (i1,i2) =
94       index (l1,u1) i1 * rangeSize (l2,u2) + index (l2,u2) i2
95
96     {-# INLINE inRange #-}
97     inRange ((l1,l2),(u1,u2)) (i1,i2) =
98       inRange (l1,u1) i1 && inRange (l2,u2) i2
99
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),
103                       i2 <- range (l2,u2),
104                       i3 <- range (l3,u3)]
105
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) * (
109       index (l1,u1) i1))
110
111     inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
112       inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
113       inRange (l3,u3) i3
114
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),
118                        i2 <- range (l2,u2),
119                        i3 <- range (l3,u3),
120                        i4 <- range (l4,u4)]
121
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) * (
126       index (l1,u1) i1)))
127
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
131
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),
135                           i2 <- range (l2,u2),
136                           i3 <- range (l3,u3),
137                           i4 <- range (l4,u4),
138                           i5 <- range (l5,u5)]
139
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) * (
145       index (l1,u1) i1))))
146
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 && 
150       inRange (l5,u5) i5
151 \end{code}
152
153 %********************************************************
154 %*                                                      *
155 \subsection{Size of @Ix@ interval}
156 %*                                                      *
157 %********************************************************
158
159 The @rangeSize@ operator returns the number of elements
160 in the range for an @Ix@ pair:
161
162 \begin{code}
163 rangeSize :: (Ix a) => (a,a) -> Int
164 rangeSize b@(l,h)
165  | l > h     = 0
166  | otherwise = index b h + 1
167
168 \end{code}