X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FBase.lhs;h=f957a6d55cffc743fe8d1285e5d8897e28feb369;hb=69daab60bb6f89433a0394182481d721dc2f42fd;hp=699deaa32223acdd9983e29b09b23ee2859d98c7;hpb=900abdfd859116754902581f9c47029e23ac6fef;p=ghc-base.git diff --git a/GHC/Base.lhs b/GHC/Base.lhs index 699deaa..f957a6d 100644 --- a/GHC/Base.lhs +++ b/GHC/Base.lhs @@ -86,7 +86,7 @@ Other Prelude modules are much easier with fewer complex dependencies. 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 @@ -196,9 +196,34 @@ class (Eq a) => Ord a where %********************************************************* \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 @@ -254,6 +279,12 @@ The rest of the prelude list functions are in GHC.List. ---------------------------------------------- \begin{code} +-- | 'foldr', applied to a binary operator, a starting value (typically +-- the right-identity of the operator), and a list, reduces the list +-- using the binary operator, from right to left: +-- +-- > foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...) + foldr :: (a -> b -> b) -> b -> [a] -> b -- foldr _ z [] = z -- foldr f z (x:xs) = f x (foldr f z xs) @@ -319,6 +350,12 @@ augment g xs = g (:) xs ---------------------------------------------- \begin{code} +-- | 'map' @f xs@ is the list obtained by applying @f@ to each element +-- of @xs@, i.e., +-- +-- > map f [x1, x2, ..., xn] == [f x1, f x2, ..., f xn] +-- > map f [x1, x2, ...] == [f x1, f x2, ...] + map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = f x : map f xs @@ -358,6 +395,13 @@ mapFB c f x ys = c (f x) ys -- append ---------------------------------------------- \begin{code} +-- | Append two lists, i.e., +-- +-- > [x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] +-- > [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...] +-- +-- If the first list is not finite, the result is the first list. + (++) :: [a] -> [a] -> [a] (++) [] ys = ys (++) (x:xs) ys = x : xs ++ ys @@ -377,8 +421,9 @@ 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. +-- 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 @@ -399,10 +444,10 @@ not :: Bool -> Bool not True = False not False = True --- |'otherwise' is defined as the value 'True'; it helps to make +-- |'otherwise' is defined as the value 'True'. It helps to make -- guards more readable. eg. -- --- > f x | x \< 0 = ... +-- > f x | x < 0 = ... -- > | otherwise = ... otherwise :: Bool otherwise = True @@ -470,11 +515,15 @@ data Ordering = LT | EQ | GT deriving (Eq, Ord) 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). +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# @@ -501,6 +550,7 @@ instance Ord Char where "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" @@ -508,6 +558,7 @@ chr (I# i#) | int2Word# i# `leWord#` int2Word# 0x10FFFF# = C# (chr# i#) 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} @@ -595,6 +646,14 @@ id x = x 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 @@ -659,6 +718,29 @@ 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} %********************************************************* %* * @@ -872,19 +954,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