> 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
> 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
"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
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 <http://www.unicode.org/> 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).
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}
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
{-# 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