X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FBase.lhs;h=9cdd7551ea517479f137d7d4b01ef2c7ce73ce85;hb=b7b024c10bdf1e3c7c9becf83ebf6e90bee8511f;hp=7c43dc3d7dfd8725010143f94792d26653a517c4;hpb=109c46aa086df8c16d01fe7ee86926918d83086c;p=ghc-base.git diff --git a/GHC/Base.lhs b/GHC/Base.lhs index 7c43dc3..9cdd755 100644 --- a/GHC/Base.lhs +++ b/GHC/Base.lhs @@ -1,11 +1,5 @@ -% ----------------------------------------------------------------------------- -% $Id: Base.lhs,v 1.8 2002/04/24 16:10:21 simonmar Exp $ -% -% (c) The University of Glasgow, 1992-2002 -% \section[GHC.Base]{Module @GHC.Base@} - The overall structure of the GHC Prelude is a bit tricky. a) We want to avoid "orphan modules", i.e. ones with instance @@ -71,16 +65,28 @@ GHC.ByteArr Types: ByteArray, MutableByteArray Other Prelude modules are much easier with fewer complex dependencies. - \begin{code} {-# OPTIONS -fno-implicit-prelude #-} +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Base +-- Copyright : (c) The University of Glasgow, 1992-2002 +-- License : see libraries/base/LICENSE +-- +-- Maintainer : cvs-ghc@haskell.org +-- Stability : internal +-- Portability : non-portable (GHC extensions) +-- +-- Basic data types and classes. +-- +----------------------------------------------------------------------------- #include "MachDeps.h" module GHC.Base ( module GHC.Base, - module GHC.Prim, -- Re-export GHC.Prim and GHC.Err, to avoid lots + module GHC.Prim, -- Re-export GHC.Prim and GHC.Err, to avoid lots module GHC.Err -- of people having to import it explicitly ) where @@ -143,6 +149,14 @@ unpackCStringUtf8# a = error "urk" %********************************************************* \begin{code} + +-- | The 'Eq' class defines equality ('==') and inequality ('/='). +-- All the basic datatypes exported by the "Prelude" are instances of 'Eq', +-- and 'Eq' may be derived for any datatype whose constituents are also +-- instances of 'Eq'. +-- +-- Minimal complete definition: either '==' or '/='. +-- class Eq a where (==), (/=) :: a -> a -> Bool @@ -362,21 +376,34 @@ mapFB c f x ys = c (f x) ys %********************************************************* \begin{code} +-- |The 'Bool' type is an enumeration. It is defined with 'False' +-- first so that the corresponding 'Enum' instance will give @'fromEnum' +-- False@ the value zero, and @'fromEnum' True@ the value 1. data Bool = False | True deriving (Eq, Ord) -- Read in GHC.Read, Show in GHC.Show -- Boolean functions -(&&), (||) :: Bool -> Bool -> Bool +-- | Boolean \"and\" +(&&) :: Bool -> Bool -> Bool True && x = x False && _ = False + +-- | Boolean \"or\" +(||) :: Bool -> Bool -> Bool True || _ = True False || x = x +-- | Boolean \"not\" not :: Bool -> Bool not True = False not False = True +-- |'otherwise' is defined as the value 'True'; it helps to make +-- guards more readable. eg. +-- +-- > f x | x \< 0 = ... +-- > | otherwise = ... otherwise :: Bool otherwise = True \end{code} @@ -396,6 +423,8 @@ need (). (We could arrange suck in () only if -fglasgow-exts, but putting it here seems more direct.) \begin{code} +-- | The unit datatype @()@ has one non-undefined member, the nullary +-- constructor @()@. data () = () instance Eq () where @@ -420,6 +449,9 @@ instance Ord () where %********************************************************* \begin{code} +-- | Represents an ordering relationship between two values: less +-- than, equal to, or greater than. An 'Ordering' is returned by +-- 'compare'. data Ordering = LT | EQ | GT deriving (Eq, Ord) -- Read in GHC.Read, Show in GHC.Show \end{code} @@ -432,8 +464,18 @@ data Ordering = LT | EQ | GT deriving (Eq, Ord) %********************************************************* \begin{code} +-- | A 'String' is a list of characters. String constants in Haskell are values +-- of type 'String'. +-- type String = [Char] +{-| The character type 'Char' is an enumeration whose values represent +Unicode characters. A character literal in Haskell has type 'Char'. + +To convert a 'Char' to or from an 'Int', use 'Prelude.toEnum' and +'Prelude.fromEnum' from the 'Enum' class respectively (equivalently +'ord' and 'chr' also do the trick). +-} data Char = C# Char# -- We don't use deriving for Eq and Ord, because for Ord the derived @@ -490,6 +532,10 @@ eqString cs1 cs2 = False \begin{code} data Int = I# Int# +-- ^A fixed-precision integer type with at least the range @[-2^29 +-- .. 2^29-1]@. The exact range for a given implementation can be +-- determined by using 'minBound' and 'maxBound' from the 'Bounded' +-- class. zeroInt, oneInt, twoInt, maxInt, minInt :: Int zeroInt = I# 0# @@ -541,6 +587,22 @@ compareInt# x# y# id :: a -> a id x = x +-- lazy function; this is just the same as id, but its unfolding +-- and strictness are over-ridden by the definition in MkId.lhs +-- That way, it does not get inlined, and the strictness analyser +-- sees it as lazy. Then the worker/wrapper phase inlines it. +-- Result: happiness +lazy :: a -> a +lazy x = x + +-- Assertion function. This simply ignores its boolean argument. +-- The compiler may rewrite it to (assertError line) +-- SLPJ: in 5.04 etc 'assert' is in GHC.Prim, +-- but from Template Haskell onwards it's simply +-- defined here in Base.lhs +assert :: Bool -> a -> a +assert pred r = r + -- constant function const :: a -> b -> a const x _ = x @@ -605,6 +667,28 @@ data (:*:) a b = a :*: b #endif \end{code} +%********************************************************* +%* * +\subsection{@getTag@} +%* * +%********************************************************* + +Returns the 'tag' of a constructor application; this function is used +by the deriving code for Eq, Ord and Enum. + +The primitive dataToTag# requires an evaluated constructor application +as its argument, so we provide getTag as a wrapper that performs the +evaluation before calling dataToTag#. We could have dataToTag# +evaluate its argument, but we prefer to do it this way because (a) +dataToTag# can be an inline primop if it doesn't need to do any +evaluation, and (b) we want to expose the evaluation to the +simplifier, because it might be possible to eliminate the evaluation +in the case when the argument is already known to be evaluated. + +\begin{code} +{-# INLINE getTag #-} +getTag x = x `seq` dataToTag# x +\end{code} %********************************************************* %* * @@ -613,11 +697,18 @@ data (:*:) a b = a :*: b %********************************************************* \begin{code} -divInt#, modInt# :: Int# -> Int# -> Int# +divInt# :: Int# -> Int# -> Int# x# `divInt#` y# - | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y# - | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y# + -- Be careful NOT to overflow if we do any additional arithmetic + -- on the arguments... the following previous version of this + -- code has problems with overflow: +-- | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y# +-- | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y# + | (x# ># 0#) && (y# <# 0#) = ((x# -# 1#) `quotInt#` y#) -# 1# + | (x# <# 0#) && (y# ># 0#) = ((x# +# 1#) `quotInt#` y#) -# 1# | otherwise = x# `quotInt#` y# + +modInt# :: Int# -> Int# -> Int# x# `modInt#` y# | (x# ># 0#) && (y# <# 0#) || (x# <# 0#) && (y# ># 0#) = if r# /=# 0# then r# +# y# else 0# @@ -771,10 +862,7 @@ unpacking the strings of error messages. \begin{code} unpackCString# :: Addr# -> [Char] {-# NOINLINE [1] unpackCString# #-} -unpackCString# a = unpackCStringList# a - -unpackCStringList# :: Addr# -> [Char] -unpackCStringList# addr +unpackCString# addr = unpack 0# where unpack nh @@ -814,19 +902,19 @@ unpackCStringUtf8# addr | ch `eqChar#` '\0'# = [] | ch `leChar#` '\x7F'# = C# ch : unpack (nh +# 1#) | ch `leChar#` '\xDF'# = - C# (chr# ((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6# +# - (ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#))) : + C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#))) : unpack (nh +# 2#) | ch `leChar#` '\xEF'# = - C# (chr# ((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12# +# - (ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 6# +# - (ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#))) : + C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#))) : unpack (nh +# 3#) | otherwise = - C# (chr# ((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18# +# - (ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 12# +# - (ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#) `uncheckedIShiftL#` 6# +# - (ord# (indexCharOffAddr# addr (nh +# 3#)) -# 0x80#))) : + C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# addr (nh +# 3#)) -# 0x80#))) : unpack (nh +# 4#) where ch = indexCharOffAddr# addr nh @@ -843,10 +931,10 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) {-# RULES "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) -"unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCStringList# a +"unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n --- There's a built-in rule (in GHC.Rules.lhs) for +-- There's a built-in rule (in PrelRules.lhs) for -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n #-}