[project @ 1997-01-06 21:08:42 by simonpj]
[ghc-hetmet.git] / ghc / lib / required / 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         Ix(range, index, inRange)
12   ) where
13
14 import {#- SOURCE #-}   IOBase  ( error )
15 import PrelNum
16 import PrelTup
17 import PrelBase
18 \end{code}
19
20 %*********************************************************
21 %*                                                      *
22 \subsection{The @Ix@ class}
23 %*                                                      *
24 %*********************************************************
25
26 \begin{code}
27 class  (Show a, Ord a) => Ix a  where
28     range               :: (a,a) -> [a]
29     index               :: (a,a) -> a -> Int
30     inRange             :: (a,a) -> a -> Bool
31 \end{code}
32
33
34 %*********************************************************
35 %*                                                      *
36 \subsection{Instances of @Ix@}
37 %*                                                      *
38 %*********************************************************
39
40 \begin{code}
41 instance  Ix Char  where
42     range (c,c')        =  [c..c']
43     index b@(c,c') ci
44         | inRange b ci  =  fromEnum ci - fromEnum c
45         | otherwise     =  error "LibIx.index: Index out of range."
46     inRange (c,c') ci   =  fromEnum c <= i && i <= fromEnum c'
47                            where i = fromEnum ci
48
49 instance  Ix Int  where
50     range (m,n)         =  [m..n]
51     index b@(m,n) i
52         | inRange b i   =  i - m
53         | otherwise     =  error "LibIx.index: Index out of range."
54     inRange (m,n) i     =  m <= i && i <= n
55
56 instance  Ix Integer  where
57     range (m,n)         =  [m..n]
58     index b@(m,n) i
59         | inRange b i   =  fromInteger (i - m)
60         | otherwise     =  error "LibIx.index: Index out of range."
61     inRange (m,n) i     =  m <= i && i <= n
62
63 ----------------------------------------------------------------------
64 instance Ix Bool where -- as derived
65     range   (l,u)   = map toEnum [fromEnum l .. fromEnum u]
66     index   (l,u) i = fromEnum i - fromEnum l
67     inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
68
69 ----------------------------------------------------------------------
70 instance Ix Ordering where -- as derived
71     range   (l,u)   = map toEnum [fromEnum l .. fromEnum u]
72     index   (l,u) i = fromEnum i - fromEnum l
73     inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
74
75
76 ----------------------------------------------------------------------
77 instance Ix () where
78     {-# INLINE range #-}
79     range   ((), ())    = [()]
80     {-# INLINE index #-}
81     index   ((), ()) () = 0
82     {-# INLINE inRange #-}
83     inRange ((), ()) () = True
84
85 ----------------------------------------------------------------------
86 instance (Ix a, Ix b) => Ix (a, b) where -- as derived
87     {-# INLINE range #-}
88     range ((l1,l2),(u1,u2))
89       = [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
90
91     {-# INLINE index #-}
92     index ((l1,l2),(u1,u2)) (i1,i2)
93       = index (l1,u1) i1 * (index (l2,u2) u2 + (I# 1#)){-rangeSize (l2,u2)-} + index (l2,u2) i2
94
95     {-# INLINE inRange #-}
96     inRange ((l1,l2),(u1,u2)) (i1,i2)
97       = inRange (l1,u1) i1 && inRange (l2,u2) i2
98
99 instance  (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3)  where
100     range ((l1,l2,l3),(u1,u2,u3)) =
101         [(i1,i2,i3) | i1 <- range (l1,u1),
102                       i2 <- range (l2,u2),
103                       i3 <- range (l3,u3)]
104
105     index ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
106       index (l3,u3) i3 + rangeSize (l3,u3) * (
107        index (l2,u2) i2 + rangeSize (l2,u2) * (
108          index (l1,u1) i1))
109       where
110         rangeSize (l,u) = index (l,u) u + (1 :: Int)
111
112     inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
113         inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
114             inRange (l3,u3) i3
115
116 instance  (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4)  where
117     range ((l1,l2,l3,l4),(u1,u2,u3,u4)) =
118         [(i1,i2,i3,i4) | i1 <- range (l1,u1),
119                          i2 <- range (l2,u2),
120                          i3 <- range (l3,u3),
121                          i4 <- range (l4,u4)]
122
123     index ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
124       index (l4,u4) i4 + rangeSize (l4,u4) * (
125        index (l3,u3) i3 + rangeSize (l3,u3) * (
126          index (l2,u2) i2 + rangeSize (l2,u2) * (
127            index (l1,u1) i1)))
128       where
129         rangeSize (l,u) = index (l,u) u + (1 :: Int)
130
131     inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
132         inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
133            inRange (l3,u3) i3 && inRange (l4,u4) i4
134
135 instance  (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5)  where
136     range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) =
137         [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1),
138                             i2 <- range (l2,u2),
139                             i3 <- range (l3,u3),
140                             i4 <- range (l4,u4),
141                             i5 <- range (l5,u5)]
142
143     index ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
144       index (l5,u5) i5 + rangeSize (l5,u5) * (
145         index (l4,u4) i4 + rangeSize (l4,u4) * (
146          index (l3,u3) i3 + rangeSize (l3,u3) * (
147            index (l2,u2) i2 + rangeSize (l2,u2) * (
148              index (l1,u1) i1))))
149       where
150         rangeSize (l,u) = index (l,u) u + (1 :: Int)
151
152     inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
153         inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
154             inRange (l3,u3) i3 && inRange (l4,u4) i4 && inRange (l5,u5) i5
155 \end{code}