\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
decls that don't belong either to a tycon or a class
defined in the same module
b) We want to avoid giant modules
So the rough structure is as follows, in (linearised) dependency order
GHC.Prim Has no implementation. It defines built-in things, and
by importing it you bring them into scope.
The source file is GHC.Prim.hi-boot, which is just
copied to make GHC.Prim.hi
GHC.PrimWrappers
Provides wrappers for built-in comparison operators.
These wrappers take unboxed operands and return a Bool.
GHC.Base Classes: Eq, Ord, Functor, Monad
Types: list, (), Int, Bool, Ordering, Char, String
Data.Tuple Types: tuples, plus instances for GHC.Base classes
GHC.Show Class: Show, plus instances for GHC.Base/GHC.Tup types
GHC.Enum Class: Enum, plus instances for GHC.Base/GHC.Tup types
Data.Maybe Type: Maybe, plus instances for GHC.Base classes
GHC.List List functions
GHC.Num Class: Num, plus instances for Int
Type: Integer, plus instances for all classes so far (Eq, Ord, Num, Show)
Integer is needed here because it is mentioned in the signature
of 'fromInteger' in class Num
GHC.Real Classes: Real, Integral, Fractional, RealFrac
plus instances for Int, Integer
Types: Ratio, Rational
plus intances for classes so far
Rational is needed here because it is mentioned in the signature
of 'toRational' in class Real
GHC.ST The ST monad, instances and a few helper functions
Ix Classes: Ix, plus instances for Int, Bool, Char, Integer, Ordering, tuples
GHC.Arr Types: Array, MutableArray, MutableVar
Arrays are used by a function in GHC.Float
GHC.Float Classes: Floating, RealFloat
Types: Float, Double, plus instances of all classes so far
This module contains everything to do with floating point.
It is a big module (900 lines)
With a bit of luck, many modules can be compiled without ever reading GHC.Float.hi
Other Prelude modules are much easier with fewer complex dependencies.
\begin{code}
#include "MachDeps.h"
module GHC.Base
(
module GHC.Base,
module GHC.Classes,
module GHC.CString,
module GHC.Magic,
module GHC.Types,
module GHC.Prim,
module GHC.PrimWrappers,
module GHC.Err
)
where
import GHC.Types
import GHC.Classes
import GHC.CString
import GHC.Magic
import GHC.Prim
import GHC.Err
import GHC.PrimWrappers
import GHC.IO (failIO)
import GHC.Tuple ()
import GHC.Integer ()
infixr 9 .
infixr 5 ++
infixl 4 <$
infixl 1 >>, >>=
infixr 0 $
default ()
\end{code}
%*********************************************************
%* *
\subsection{DEBUGGING STUFF}
%* (for use when compiling GHC.Base itself doesn't work)
%* *
%*********************************************************
\begin{code}
\end{code}
%*********************************************************
%* *
\subsection{Monadic classes @Functor@, @Monad@ }
%* *
%*********************************************************
\begin{code}
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
(<$) = fmap . const
class Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
(>>) :: forall a b. m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
m >> k = m >>= \_ -> k
fail s = error s
instance Functor ((->) r) where
fmap = (.)
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
instance Functor ((,) a) where
fmap f (x,y) = (x, f y)
\end{code}
%*********************************************************
%* *
\subsection{The list type}
%* *
%*********************************************************
\begin{code}
instance Functor [] where
fmap = map
instance Monad [] where
m >>= k = foldr ((++) . k) [] m
m >> k = foldr ((++) . (\ _ -> k)) [] m
return x = [x]
fail _ = []
\end{code}
A few list functions that appear here because they are used here.
The rest of the prelude list functions are in GHC.List.
----------------------------------------------
-- foldr/build/augment
----------------------------------------------
\begin{code}
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
build g = g (:) []
augment :: forall a. (forall b. (a->b->b) -> b -> b) -> [a] -> [a]
augment g xs = g (:) xs
\end{code}
----------------------------------------------
-- map
----------------------------------------------
\begin{code}
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
mapFB :: (elt -> lst -> lst) -> (a -> elt) -> a -> lst -> lst
mapFB c f = \x ys -> c (f x) ys
\end{code}
----------------------------------------------
-- append
----------------------------------------------
\begin{code}
(++) :: [a] -> [a] -> [a]
(++) [] ys = ys
(++) (x:xs) ys = x : xs ++ ys
\end{code}
%*********************************************************
%* *
\subsection{Type @Bool@}
%* *
%*********************************************************
\begin{code}
otherwise :: Bool
otherwise = True
\end{code}
%*********************************************************
%* *
\subsection{Type @Char@ and @String@}
%* *
%*********************************************************
\begin{code}
type String = [Char]
unsafeChr :: Int -> Char
unsafeChr (I# i#) = C# (chr# i#)
ord :: Char -> Int
ord (C# c#) = I# (ord# c#)
\end{code}
String equality is used when desugaring pattern-matches against strings.
\begin{code}
eqString :: String -> String -> Bool
eqString [] [] = True
eqString (c1:cs1) (c2:cs2) = c1 == c2 && cs1 `eqString` cs2
eqString _ _ = False
\end{code}
%*********************************************************
%* *
\subsection{Type @Int@}
%* *
%*********************************************************
\begin{code}
maxInt, minInt :: Int
#if WORD_SIZE_IN_BITS == 31
minInt = I# (0x40000000#)
maxInt = I# 0x3FFFFFFF#
#elif WORD_SIZE_IN_BITS == 32
minInt = I# (0x80000000#)
maxInt = I# 0x7FFFFFFF#
#else
minInt = I# (0x8000000000000000#)
maxInt = I# 0x7FFFFFFFFFFFFFFF#
#endif
\end{code}
%*********************************************************
%* *
\subsection{The function type}
%* *
%*********************************************************
\begin{code}
id :: a -> a
id x = x
assert :: Bool -> a -> a
assert _pred r = r
breakpoint :: a -> a
breakpoint r = r
breakpointCond :: Bool -> a -> a
breakpointCond _ r = r
data Opaque = forall a. O a
const :: a -> b -> a
const x _ = x
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x
($) :: (a -> b) -> a -> b
f $ x = f x
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f = go
where
go x | p x = x
| otherwise = go (f x)
asTypeOf :: a -> a -> a
asTypeOf = const
\end{code}
%*********************************************************
%* *
\subsection{@Functor@ and @Monad@ instances for @IO@}
%* *
%*********************************************************
\begin{code}
instance Functor IO where
fmap f x = x >>= (return . f)
instance Monad IO where
m >> k = m >>= \ _ -> k
return = returnIO
(>>=) = bindIO
fail s = failIO s
returnIO :: a -> IO a
returnIO x = IO $ \ s -> (# s, x #)
bindIO :: IO a -> (a -> IO b) -> IO b
bindIO (IO m) k = IO $ \ s -> case m s of (# new_s, a #) -> unIO (k a) new_s
thenIO :: IO a -> IO b -> IO b
thenIO (IO m) k = IO $ \ s -> case m s of (# new_s, _ #) -> unIO k new_s
unIO :: IO a -> (State# RealWorld -> (# State# RealWorld, a #))
unIO (IO a) = a
\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}
getTag :: a -> Int#
getTag x = x `seq` dataToTag# x
\end{code}
%*********************************************************
%* *
\subsection{Numeric primops}
%* *
%*********************************************************
Definitions of the boxed PrimOps; these will be
used in the case of partial applications, etc.
\begin{code}
quotInt, remInt, divInt, modInt :: Int -> Int -> Int
(I# x) `quotInt` (I# y) = I# (x `quotInt#` y)
(I# x) `remInt` (I# y) = I# (x `remInt#` y)
(I# x) `divInt` (I# y) = I# (x `divInt#` y)
(I# x) `modInt` (I# y) = I# (x `modInt#` y)
quotRemInt :: Int -> Int -> (Int, Int)
(I# x) `quotRemInt` (I# y) = case x `quotRemInt#` y of
(# q, r #) ->
(I# q, I# r)
divModInt :: Int -> Int -> (Int, Int)
(I# x) `divModInt` (I# y) = case x `divModInt#` y of
(# q, r #) -> (I# q, I# r)
divModInt# :: Int# -> Int# -> (# Int#, Int# #)
x# `divModInt#` y#
| (x# ># 0#) && (y# <# 0#) = case (x# -# 1#) `quotRemInt#` y# of
(# q, r #) -> (# q -# 1#, r +# y# +# 1# #)
| (x# <# 0#) && (y# ># 0#) = case (x# +# 1#) `quotRemInt#` y# of
(# q, r #) -> (# q -# 1#, r +# y# -# 1# #)
| otherwise = x# `quotRemInt#` y#
shiftL# :: Word# -> Int# -> Word#
a `shiftL#` b | b >=# WORD_SIZE_IN_BITS# = 0##
| otherwise = a `uncheckedShiftL#` b
shiftRL# :: Word# -> Int# -> Word#
a `shiftRL#` b | b >=# WORD_SIZE_IN_BITS# = 0##
| otherwise = a `uncheckedShiftRL#` b
iShiftL# :: Int# -> Int# -> Int#
a `iShiftL#` b | b >=# WORD_SIZE_IN_BITS# = 0#
| otherwise = a `uncheckedIShiftL#` b
iShiftRA# :: Int# -> Int# -> Int#
a `iShiftRA#` b | b >=# WORD_SIZE_IN_BITS# = if a <# 0# then (1#) else 0#
| otherwise = a `uncheckedIShiftRA#` b
iShiftRL# :: Int# -> Int# -> Int#
a `iShiftRL#` b | b >=# WORD_SIZE_IN_BITS# = 0#
| otherwise = a `uncheckedIShiftRL#` b
\end{code}
#ifdef __HADDOCK__
\begin{code}
data RealWorld
\end{code}
#endif