Commit ed69dbe9 authored by simonmar's avatar simonmar
Browse files

[project @ 2001-08-29 09:34:05 by simonmar]

Changes to the Ix class from the revised Haskell 98 report:

  - Ord is no longer a superclass of Ix.

  - rangeSize is now a class member, as there are cases when
    it is useful to be able to override it.  As a result, GHC's
    performance-improving "unsafeRangeSize" function also has to be
    a class method just in case the programmer has overriden
    rangeSize.  Of course, unsafeRangeSize isn't visible when just
    importing Ix.

  - Added unsafeRangeSize bindings to all our standard Ix instances.

  - Improved the Ix instances for Int{8,16,32,64} and
    Word{8,16,32,64} by defining unsafeIndex instead of index, and
    providing a definition of unsafeRangeSize.

I hope I haven't mucked anything up :) The array tests all pass
successfully, except for arr016 which depended on Ord being a
superclass of Ix.  I'll commit changes to this test shortly.
parent e421cf95
% -----------------------------------------------------------------------------
% $Id: Ix.lhs,v 1.18 2000/06/30 13:39:35 simonmar Exp $
% $Id: Ix.lhs,v 1.19 2001/08/29 09:34:05 simonmar Exp $
%
% (c) The University of Glasgow, 1994-2000
%
......@@ -13,8 +13,8 @@ module Ix
( range -- :: (Ix a) => (a,a) -> [a]
, index -- :: (Ix a) => (a,a) -> a -> Int
, inRange -- :: (Ix a) => (a,a) -> a -> Bool
, rangeSize -- :: (Ix a) => (a,a) -> Int
)
, rangeSize -- :: (Ix a) => (a,a) -> Int
-- Ix instances:
--
-- Ix Char
......
% -----------------------------------------------------------------------------
% $Id: PrelArr.lhs,v 1.28 2001/05/01 09:16:56 qrczak Exp $
% $Id: PrelArr.lhs,v 1.29 2001/08/29 09:34:05 simonmar Exp $
%
% (c) The University of Glasgow, 1994-2000
%
......@@ -37,17 +37,38 @@ default ()
%*********************************************************
\begin{code}
class (Ord a) => Ix a where
class Ix a where
range :: (a,a) -> [a]
index, unsafeIndex :: (a,a) -> a -> Int
inRange :: (a,a) -> a -> Bool
rangeSize :: (a,a) -> Int
unsafeRangeSize :: (a,a) -> Int
-- Must specify one of index, unsafeIndex
index b i | inRange b i = unsafeIndex b i
| otherwise = error "Error in array index"
unsafeIndex b i = index b i
-- As long as you don't override the default rangeSize,
-- you can specify unsafeRangeSize as follows, to speed up
-- some operations:
--
-- unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
--
rangeSize b@(_l,h) | inRange b h = unsafeIndex b h + 1
| otherwise = 0
unsafeRangeSize b = rangeSize b
\end{code}
Note that the following is NOT right
rangeSize (l,h) | l <= h = index b h + 1
| otherwise = 0
Because it might be the case that l<h, but the range
is nevertheless empty. Consider
((1,2),(2,1))
Here l<h, but the second index ranges from 2..1 and
hence is empty
%*********************************************************
%* *
......@@ -80,6 +101,8 @@ instance Ix Char where
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance Ix Int where
{-# INLINE range #-}
......@@ -96,6 +119,8 @@ instance Ix Int where
{-# INLINE inRange #-}
inRange (I# m,I# n) (I# i) = m <=# i && i <=# n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance Ix Integer where
{-# INLINE range #-}
......@@ -109,6 +134,7 @@ instance Ix Integer where
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance Ix Bool where -- as derived
......@@ -123,6 +149,8 @@ instance Ix Bool where -- as derived
inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance Ix Ordering where -- as derived
{-# INLINE range #-}
......@@ -136,6 +164,8 @@ instance Ix Ordering where -- as derived
inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance Ix () where
{-# INLINE range #-}
......@@ -147,6 +177,7 @@ instance Ix () where
{-# INLINE index #-}
index b i = unsafeIndex b i
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
----------------------------------------------------------------------
instance (Ix a, Ix b) => Ix (a, b) where -- as derived
......@@ -164,6 +195,8 @@ instance (Ix a, Ix b) => Ix (a, b) where -- as derived
inRange ((l1,l2),(u1,u2)) (i1,i2) =
inRange (l1,u1) i1 && inRange (l2,u2) i2
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
-- Default method for index
----------------------------------------------------------------------
......@@ -184,6 +217,8 @@ instance (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3) where
inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
inRange (l3,u3) i3
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
-- Default method for index
----------------------------------------------------------------------
......@@ -204,6 +239,8 @@ instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where
inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
inRange (l3,u3) i3 && inRange (l4,u4) i4
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
-- Default method for index
instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
......@@ -226,40 +263,9 @@ instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where
inRange (l3,u3) i3 && inRange (l4,u4) i4 &&
inRange (l5,u5) i5
-- Default method for index
\end{code}
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
%********************************************************
%* *
\subsection{Size of @Ix@ interval}
%* *
%********************************************************
The @rangeSize@ operator returns the number of elements
in the range for an @Ix@ pair.
\begin{code}
{-# SPECIALISE unsafeRangeSize :: (Int,Int) -> Int #-}
{-# SPECIALISE unsafeRangeSize :: ((Int,Int),(Int,Int)) -> Int #-}
unsafeRangeSize :: (Ix a) => (a,a) -> Int
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
{-# SPECIALISE rangeSize :: (Int,Int) -> Int #-}
{-# SPECIALISE rangeSize :: ((Int,Int),(Int,Int)) -> Int #-}
rangeSize :: (Ix a) => (a,a) -> Int
rangeSize b@(_l,h) | inRange b h = unsafeIndex b h + 1
| otherwise = 0
-- Note that the following is NOT right
-- rangeSize (l,h) | l <= h = index b h + 1
-- | otherwise = 0
--
-- Because it might be the case that l<h, but the range
-- is nevertheless empty. Consider
-- ((1,2),(2,1))
-- Here l<h, but the second index ranges from 2..1 and
-- hence is empty
-- Default method for index
\end{code}
......@@ -442,14 +448,14 @@ ixmap (l,u) f arr =
unsafeArray (l,u) [(unsafeIndex (l,u) i, arr ! f i) | i <- range (l,u)]
{-# INLINE eqArray #-}
eqArray :: (Ix i, Eq e) => Array i e -> Array i e -> Bool
eqArray :: (Ix i, Eq i, Eq e) => Array i e -> Array i e -> Bool
eqArray arr1@(Array l1 u1 _) arr2@(Array l2 u2 _) =
if rangeSize (l1,u1) == 0 then rangeSize (l2,u2) == 0 else
l1 == l2 && u1 == u2 &&
and [unsafeAt arr1 i == unsafeAt arr2 i | i <- [0 .. rangeSize (l1,u1) - 1]]
{-# INLINE cmpArray #-}
cmpArray :: (Ix i, Ord e) => Array i e -> Array i e -> Ordering
cmpArray :: (Ix i, Ord i, Ord e) => Array i e -> Array i e -> Ordering
cmpArray arr1 arr2 = compare (assocs arr1) (assocs arr2)
{-# INLINE cmpIntArray #-}
......@@ -479,10 +485,10 @@ cmpIntArray arr1@(Array l1 u1 _) arr2@(Array l2 u2 _) =
instance Ix i => Functor (Array i) where
fmap = amap
instance (Ix i, Eq e) => Eq (Array i e) where
instance (Ix i, Eq i, Eq e) => Eq (Array i e) where
(==) = eqArray
instance (Ix i, Ord e) => Ord (Array i e) where
instance (Ix i, Ord i, Ord e) => Ord (Array i e) where
compare = cmpArray
instance (Ix a, Show a, Show b) => Show (Array a b) where
......
% -----------------------------------------------------------------------------
% $Id: PrelEnum.lhs,v 1.15 2001/08/17 17:18:54 apt Exp $
% $Id: PrelEnum.lhs,v 1.16 2001/08/29 09:34:05 simonmar Exp $
%
% (c) The University of Glasgow, 1992-2000
% (c) The University of Glasgow, 1992-2001
%
\section[PrelBounded]{Module @PrelBounded@}
Instances of Bounded for various datatypes.
Instances of Bounded and Enum for various datatypes.
\begin{code}
{-# OPTIONS -fno-implicit-prelude #-}
......
......@@ -96,11 +96,10 @@ instance Bounded Int8 where
maxBound = 0x7F
instance Ix Int8 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Int8"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Int8 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
......@@ -202,11 +201,10 @@ instance Bounded Int16 where
maxBound = 0x7FFF
instance Ix Int16 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Int16"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Int16 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
......@@ -493,11 +491,10 @@ instance Bounded Int32 where
maxBound = 0x7FFFFFFF
instance Ix Int32 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Int32"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
------------------------------------------------------------------------
-- type Int64
......@@ -741,9 +738,8 @@ instance Bounded Int64 where
maxBound = 0x7FFFFFFFFFFFFFFF
instance Ix Int64 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Int64"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
\end{code}
......@@ -140,11 +140,10 @@ instance Bounded Word where
#endif
instance Ix Word where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Word"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word where
readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
......@@ -240,11 +239,10 @@ instance Bounded Word8 where
maxBound = 0xFF
instance Ix Word8 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Word8"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word8 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
......@@ -341,11 +339,10 @@ instance Bounded Word16 where
maxBound = 0xFFFF
instance Ix Word16 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Word16"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word16 where
readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
......@@ -615,11 +612,10 @@ instance Bounded Word32 where
maxBound = 0xFFFFFFFF
instance Ix Word32 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Word32"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word32 where
#if WORD_SIZE_IN_BITS < 33
......@@ -845,11 +841,10 @@ instance Bounded Word64 where
maxBound = 0xFFFFFFFFFFFFFFFF
instance Ix Word64 where
range (m,n) = [m..n]
index b@(m,_) i
| inRange b i = fromIntegral (i - m)
| otherwise = indexError b i "Word64"
inRange (m,n) i = m <= i && i <= n
range (m,n) = [m..n]
unsafeIndex b@(m,_) i = fromIntegral (i - m)
inRange (m,n) i = m <= i && i <= n
unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
instance Read Word64 where
readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment