GHC/Base.lhs (original) (raw)

\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.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.Types, module GHC.Prim,
module GHC.Err
) where

import GHC.Types import GHC.Classes import GHC.CString import GHC.Prim import GHC.Err 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

lazy :: a -> a lazy 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 x | p x = x | otherwise = until p f (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

#if WORD_SIZE_IN_BITS == 32

#endif

\end{code} #ifdef __HADDOCK__ \begin{code}

data RealWorld

\end{code} #endif