X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FBase.lhs;h=cf3c5a3e099bb724b486dbf4b8d45044d666de66;hb=7a73aaf70fefb4b30c9159f5d15035f8e9c6e114;hp=6a6926917f6cdbed4e0055645bca05b1dbd1cd3c;hpb=aaf764b3ad8b1816d68b5f27299eac125f08e1a5;p=haskell-directory.git diff --git a/GHC/Base.lhs b/GHC/Base.lhs index 6a69269..cf3c5a3 100644 --- a/GHC/Base.lhs +++ b/GHC/Base.lhs @@ -81,6 +81,7 @@ Other Prelude modules are much easier with fewer complex dependencies. #include "MachDeps.h" +-- #hide module GHC.Base ( module GHC.Base, @@ -208,14 +209,22 @@ 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. +The instances of 'Functor' for lists, 'Data.Maybe.Maybe' and 'System.IO.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/. +{- | The 'Monad' class defines the basic operations over a /monad/, +a concept from a branch of mathematics known as /category theory/. +From the perspective of a Haskell programmer, however, it is best to +think of a monad as an /abstract datatype/ of actions. +Haskell's @do@ expressions provide a convenient syntax for writing +monadic expressions. + +Minimal complete definition: '>>=' and 'return'. + Instances of 'Monad' should satisfy the following laws: > return a >>= k == k a @@ -226,16 +235,26 @@ 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. +The instances of 'Monad' for lists, 'Data.Maybe.Maybe' and 'System.IO.IO' +defined in the "Prelude" satisfy these laws. -} class Monad m where + -- | Sequentially compose two actions, passing any value produced + -- by the first as an argument to the second. (>>=) :: forall a b. m a -> (a -> m b) -> m b + -- | Sequentially compose two actions, discarding any value produced + -- by the first, like sequencing operators (such as the semicolon) + -- in imperative languages. (>>) :: forall a b. m a -> m b -> m b -- Explicit for-alls so that we know what order to -- give type arguments when desugaring + + -- | Inject a value into the monadic type. return :: a -> m a + -- | Fail with a message. This operation is not part of the + -- mathematical definition of a monad, but is invoked on pattern-match + -- failure in a @do@ expression. fail :: String -> m a m >> k = m >>= \_ -> k @@ -303,6 +322,15 @@ foldr k z xs = go xs go [] = z go (y:ys) = y `k` go ys +-- | A list producer that can be fused with 'foldr'. +-- This function is merely +-- +-- > build g = g (:) [] +-- +-- but GHC's simplifier will transform an expression of the form +-- @'foldr' k z ('build' g)@, which may arise after inlining, to @g k z@, +-- which avoids producing an intermediate list. + build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a] {-# INLINE [1] build #-} -- The INLINE is important, even though build is tiny, @@ -314,6 +342,15 @@ build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a] build g = g (:) [] +-- | A list producer that can be fused with 'foldr'. +-- This function is merely +-- +-- > augment g xs = g (:) xs +-- +-- but GHC's simplifier will transform an expression of the form +-- @'foldr' k z ('augment' g xs)@, which may arise after inlining, to +-- @g k ('foldr' k z xs)@, which avoids producing an intermediate list. + augment :: forall a. (forall b. (a->b->b) -> b -> b) -> [a] -> [a] {-# INLINE [1] augment #-} augment g xs = g (:) xs @@ -325,8 +362,8 @@ augment g xs = g (:) xs "foldr/augment" forall k z xs (g::forall b. (a->b->b) -> b -> b) . foldr k z (augment g xs) = g k (foldr k z xs) -"foldr/id" foldr (:) [] = \x->x -"foldr/app" [1] forall xs ys. foldr (:) ys xs = xs ++ ys +"foldr/id" foldr (:) [] = \x -> x +"foldr/app" [1] forall ys. foldr (:) ys = \xs -> xs ++ ys -- Only activate this from phase 1, because that's -- when we disable the rule that expands (++) into foldr @@ -523,7 +560,8 @@ data Ordering = LT | EQ | GT deriving (Eq, Ord) type String = [Char] {-| The character type 'Char' is an enumeration whose values represent -Unicode (or equivalently ISO 10646) characters. +Unicode (or equivalently ISO\/IEC 10646) characters +(see for details). 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). @@ -580,6 +618,8 @@ eqString (c1:cs1) (c2:cs2) = c1 == c2 && cs1 `eqString` cs2 eqString cs1 cs2 = False {-# RULES "eqString" (==) = eqString #-} +-- eqString also has a BuiltInRule in PrelRules.lhs: +-- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2) = s1==s2 \end{code} @@ -645,23 +685,54 @@ 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 +-- | The call '(lazy e)' means the same as 'e', but 'lazy' has a +-- magical strictness property: it is lazy in its first argument, +-- even though its semantics is strict. lazy :: a -> a lazy x = x +-- Implementation note: its strictness and unfolding are over-ridden +-- by the definition in MkId.lhs; in both cases to nothing at all. +-- That way, 'lazy' does not get inlined, and the strictness analyser +-- sees it as lazy. Then the worker/wrapper phase inlines it. +-- Result: happiness + --- | Assertion function. This simply ignores its boolean argument. +-- | The call '(inline f)' reduces to 'f', but 'inline' has a BuiltInRule +-- that tries to inline 'f' (if it has an unfolding) unconditionally +-- The 'NOINLINE' pragma arranges that inline only gets inlined (and +-- hence eliminated) late in compilation, after the rule has had +-- a god chance to fire. +inline :: a -> a +{-# NOINLINE[0] inline #-} +inline x = x + +-- Assertion function. This simply ignores its boolean argument. -- The compiler may rewrite it to @('assertError' line)@. +-- | If the first argument evaluates to 'True', then the result is the +-- second argument. Otherwise an 'AssertionFailed' exception is raised, +-- containing a 'String' with the source file and line number of the +-- call to 'assert'. +-- +-- Assertions can normally be turned on or off with a compiler flag +-- (for GHC, assertions are normally on unless optimisation is turned on +-- with @-O@ or the @-fignore-asserts@ +-- option is given). When assertions are turned off, the first +-- argument to 'assert' is ignored, and the second argument is +-- returned as the result. + -- 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 - + +breakpoint :: a -> a +breakpoint r = r + +breakpointCond :: Bool -> a -> a +breakpointCond _ r = r + -- | Constant function. const :: a -> b -> a const x _ = x @@ -865,22 +936,33 @@ gtInt, geInt, eqInt, neInt, ltInt, leInt :: Int -> Int -> Bool -- Note that these wrappers still produce undefined results when the -- second argument (the shift amount) is negative. -shiftL#, shiftRL# :: Word# -> Int# -> Word# - +-- | Shift the argument left by the specified number of bits +-- (which must be non-negative). +shiftL# :: Word# -> Int# -> Word# a `shiftL#` b | b >=# WORD_SIZE_IN_BITS# = int2Word# 0# | otherwise = a `uncheckedShiftL#` b +-- | Shift the argument right by the specified number of bits +-- (which must be non-negative). +shiftRL# :: Word# -> Int# -> Word# a `shiftRL#` b | b >=# WORD_SIZE_IN_BITS# = int2Word# 0# | otherwise = a `uncheckedShiftRL#` b -iShiftL#, iShiftRA#, iShiftRL# :: Int# -> Int# -> Int# - +-- | Shift the argument left by the specified number of bits +-- (which must be non-negative). +iShiftL# :: Int# -> Int# -> Int# a `iShiftL#` b | b >=# WORD_SIZE_IN_BITS# = 0# | otherwise = a `uncheckedIShiftL#` b +-- | Shift the argument right (signed) by the specified number of bits +-- (which must be non-negative). +iShiftRA# :: Int# -> Int# -> Int# a `iShiftRA#` b | b >=# WORD_SIZE_IN_BITS# = if a <# 0# then (-1#) else 0# | otherwise = a `uncheckedIShiftRA#` b +-- | Shift the argument right (unsigned) by the specified number of bits +-- (which must be non-negative). +iShiftRL# :: Int# -> Int# -> Int# a `iShiftRL#` b | b >=# WORD_SIZE_IN_BITS# = 0# | otherwise = a `uncheckedIShiftRL#` b @@ -933,6 +1015,9 @@ unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a {-# NOINLINE [0] unpackFoldrCString# #-} -- Don't inline till right at the end; -- usually the unpack-list rule turns it into unpackCStringList +-- It also has a BuiltInRule in PrelRules.lhs: +-- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) +-- = unpackFoldrCString# "foobaz" c n unpackFoldrCString# addr f z = unpack 0# where