-% -----------------------------------------------------------------------------
-% $Id: Base.lhs,v 1.5 2002/02/05 17:32:26 simonmar Exp $
-%
-% (c) The University of Glasgow, 1992-2000
-%
\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
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
-import {-# SOURCE #-} GHC.Prim
+import GHC.Prim
import {-# SOURCE #-} GHC.Err
infixr 9 .
%*********************************************************
\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
%*********************************************************
\begin{code}
+{- | The 'Functor' class is used for types that can be mapped over.
+Instances of 'Functor' should satisfy the following laws:
+
+> fmap id == id
+> fmap (f . g) == fmap f . fmap g
+
+The instances of 'Functor' for lists, 'Maybe' and 'IO' defined in the "Prelude"
+satisfy these laws.
+-}
+
class Functor f where
fmap :: (a -> b) -> f a -> f b
+{- | The 'Monad' class defines the basic operations over a /monad/.
+Instances of 'Monad' should satisfy the following laws:
+
+> return a >>= k == k a
+> m >>= return == m
+> m >>= (\x -> k x >>= h) == (m >>= k) >>= h
+
+Instances of both 'Monad' and 'Functor' should additionally satisfy the law:
+
+> fmap f xs == xs >>= return . f
+
+The instances of 'Monad' for lists, 'Maybe' and 'IO' defined in the "Prelude"
+satisfy these laws.
+-}
+
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
%*********************************************************
\begin{code}
+-- |The 'Bool' type is an enumeration. It is defined with 'False'
+-- first so that the corresponding 'Prelude.Enum' instance will give
+-- 'Prelude.fromEnum' 'False' the value zero, and
+-- 'Prelude.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}
it here seems more direct.)
\begin{code}
+-- | The unit datatype @()@ has one non-undefined member, the nullary
+-- constructor @()@.
data () = ()
instance Eq () 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}
%*********************************************************
\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 (or equivalently ISO 10646) characters.
+This set extends the ISO 8859-1 (Latin-1) character set
+(the first 256 charachers), which is itself an extension of the ASCII
+character set (the first 128 characters).
+A character literal in Haskell has type 'Char'.
+
+To convert a 'Char' to or from the corresponding 'Int' value defined
+by Unicode, use 'Prelude.toEnum' and 'Prelude.fromEnum' from the
+'Prelude.Enum' class respectively (or equivalently 'ord' and 'chr').
+-}
data Char = C# Char#
-- We don't use deriving for Eq and Ord, because for Ord the derived
"x# `ltChar#` x#" forall x#. x# `ltChar#` x# = False
#-}
+-- | The 'Prelude.toEnum' method restricted to the type 'Data.Char.Char'.
chr :: Int -> Char
chr (I# i#) | int2Word# i# `leWord#` int2Word# 0x10FFFF# = C# (chr# i#)
| otherwise = error "Prelude.chr: bad argument"
unsafeChr :: Int -> Char
unsafeChr (I# i#) = C# (chr# i#)
+-- | The 'Prelude.fromEnum' method restricted to the type 'Data.Char.Char'.
ord :: Char -> Int
ord (C# c#) = I# (ord# c#)
\end{code}
\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#
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
\begin{code}
data Unit = Unit
-data a :+: b = Inl a | Inr b
-data a :*: b = a :*: b
+#ifndef __HADDOCK__
+data (:+:) a b = Inl a | Inr b
+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 :: a -> Int#
+getTag x = x `seq` dataToTag# x
+\end{code}
%*********************************************************
%* *
%*********************************************************
\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#
"x# <=# x#" forall x#. x# <=# x# = True
#-}
+{-# RULES
+"plusFloat x 0.0" forall x#. plusFloat# x# 0.0# = x#
+"plusFloat 0.0 x" forall x#. plusFloat# 0.0# x# = x#
+"minusFloat x 0.0" forall x#. minusFloat# x# 0.0# = x#
+"minusFloat x x" forall x#. minusFloat# x# x# = 0.0#
+"timesFloat x 0.0" forall x#. timesFloat# x# 0.0# = 0.0#
+"timesFloat0.0 x" forall x#. timesFloat# 0.0# x# = 0.0#
+"timesFloat x 1.0" forall x#. timesFloat# x# 1.0# = x#
+"timesFloat 1.0 x" forall x#. timesFloat# 1.0# x# = x#
+"divideFloat x 1.0" forall x#. divideFloat# x# 1.0# = x#
+ #-}
+
+{-# RULES
+"plusDouble x 0.0" forall x#. (+##) x# 0.0## = x#
+"plusDouble 0.0 x" forall x#. (+##) 0.0## x# = x#
+"minusDouble x 0.0" forall x#. (-##) x# 0.0## = x#
+"minusDouble x x" forall x#. (-##) x# x# = 0.0##
+"timesDouble x 0.0" forall x#. (*##) x# 0.0## = 0.0##
+"timesDouble 0.0 x" forall x#. (*##) 0.0## x# = 0.0##
+"timesDouble x 1.0" forall x#. (*##) x# 1.0## = x#
+"timesDouble 1.0 x" forall x#. (*##) 1.0## x# = x#
+"divideDouble x 1.0" forall x#. (/##) x# 1.0## = x#
+ #-}
+
-- Wrappers for the shift operations. The uncheckedShift# family are
-- undefined when the amount being shifted by is greater than the size
-- in bits of Int#, so these wrappers perform a check and return
\begin{code}
unpackCString# :: Addr# -> [Char]
{-# NOINLINE [1] unpackCString# #-}
-unpackCString# a = unpackCStringList# a
-
-unpackCStringList# :: Addr# -> [Char]
-unpackCStringList# addr
+unpackCString# addr
= unpack 0#
where
unpack nh
| 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
{-# 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
#-}