X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=60466911db8961a5f191869378e432776849a3aa;hp=71a0752669331aaf1e73f7d6673539ee6413986b;hb=f04dead93a15af1cb818172f207b8a81d2c81298;hpb=69f8ed93800605d8df011388450d6d3bb9ca6071 diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 71a0752..6046691 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -82,7 +82,7 @@ documentation describes all the libraries that come with GHC. , , , - , + , , , , @@ -860,33 +860,45 @@ it, you can use the flag. The recursive do-notation - The recursive do-notation (also known as mdo-notation) is implemented as described in -A recursive do for Haskell, -by Levent Erkok, John Launchbury, -Haskell Workshop 2002, pages: 29-37. Pittsburgh, Pennsylvania. -This paper is essential reading for anyone making non-trivial use of mdo-notation, -and we do not repeat it here. - -The do-notation of Haskell does not allow recursive bindings, +The do-notation of Haskell 98 does not allow recursive bindings, that is, the variables bound in a do-expression are visible only in the textually following code block. Compare this to a let-expression, where bound variables are visible in the entire binding group. It turns out that several applications can benefit from recursive bindings in -the do-notation, and this extension provides the necessary syntactic support. +the do-notation. The flag provides the necessary syntactic support. -Here is a simple (yet contrived) example: - +Here is a simple (albeit contrived) example: +{-# LANGUAGE DoRec #-} import Control.Monad.Fix -justOnes = mdo xs <- Just (1:xs) - return xs +justOnes = do { rec { xs <- Just (1:xs) } + ; return (map negate xs) } +The rec +As you can guess justOnes will evaluate to Just [-1,-1,-1,.... + -As you can guess justOnes will evaluate to Just [1,1,1,.... +The background and motivation for recusrive do-notation is described in +A recursive do for Haskell, +by Levent Erkok, John Launchbury, +Haskell Workshop 2002, pages: 29-37. Pittsburgh, Pennsylvania. +This paper is essential reading for anyone making non-trivial use of mdo-notation, +and we do not repeat it here. However, note that GHC uses a different syntax than the one +in the paper. + +Details of recursive do-notation + +The recursive do-notation is enabled with the flag or, equivalently, +the LANGUAGE pragma . It introduces the single new keyword "rec", +which wraps a mutually-recusrive group of monadic statements, +producing a single statement. Similar to a let +statement, the variables bound in the rec are +visible throughout the rec group, and below it. + The Control.Monad.Fix library introduces the MonadFix class. Its definition is: @@ -899,30 +911,35 @@ The function mfix dictates how the required recursion operation should be performed. For example, justOnes desugars as follows: -justOnes = mfix (\xs' -> do { xs <- Just (1:xs'); return xs } +justOnes = do { xs <- mfix (\xs' -> do { xs <- Just (1:xs'); return xs }) + ; return (map negate xs) } -For full details of the way in which mdo is typechecked and desugared, see -the paper A recursive do for Haskell. -In particular, GHC implements the segmentation technique described in Section 3.2 of the paper. - - -If recursive bindings are required for a monad, -then that monad must be declared an instance of the MonadFix class. -The following instances of MonadFix are automatically provided: List, Maybe, IO. -Furthermore, the Control.Monad.ST and Control.Monad.ST.Lazy modules provide the instances of the MonadFix class -for Haskell's internal state monad (strict and lazy, respectively). +In general, a rec statment rec ss +is desugared to the statement + + vs <- mfix (\~vs -> do { ss + ; return vs }) + +where vs is a tuple of the varaibles bound by ss. +Moreover, the original rec typechecks exactly +when the above desugared version would do so. (For example, this means that +the variables vs are all monomorphic in the statements +following the rec, because they are bound by a lambda.) -Here are some important points in using the recursive-do notation: +Here are some other important points in using the recursive-do notation: -The recursive version of the do-notation uses the keyword mdo (rather -than do). +It is enabled with the flag -XDoRec, which is in turn implied by +-fglasgow-exts. -It is enabled with the flag -XRecursiveDo, which is in turn implied by --fglasgow-exts. +If recursive bindings are required for a monad, +then that monad must be declared an instance of the MonadFix class. +The following instances of MonadFix are automatically provided: List, Maybe, IO. +Furthermore, the Control.Monad.ST and Control.Monad.ST.Lazy modules provide the instances of the MonadFix class +for Haskell's internal state monad (strict and lazy, respectively). @@ -932,20 +949,31 @@ be distinct (Section 3.3 of the paper). -Variables bound by a let statement in an mdo -are monomorphic in the mdo (Section 3.1 of the paper). However -GHC breaks the mdo into segments to enhance polymorphism, -and improve termination (Section 3.2 of the paper). +Similar to let-bindings, GHC implements the segmentation technique described in Section 3.2 of +A recursive do for Haskell, +to break up a single rec statement into a sequenc e of statements with +rec groups of minimal size. This +improves polymorphism, and reduces the size of the recursive "knot". + + + +<para> GHC used to support the flag <option>-XREecursiveDo</option>, +which enabled the keyword <literal>mdo</literal>, precisely as described in +<ulink url="http://citeseer.ist.psu.edu/erk02recursive.html">A recursive do for Haskell</ulink>, +but this is now deprecated. Instead of <literal>mdo { Q; e }</literal>, write +<literal>do { rec Q; e }</literal>. +</para> <para> Historical note: The old implementation of the mdo-notation (and most of the existing documents) used the name <literal>MonadRec</literal> for the class and the corresponding library. This name is not supported by GHC. </para> +</sect3> </sect2>