diff options
author | simonpj@microsoft.com <unknown> | 2009-10-29 11:47:26 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2009-10-29 11:47:26 +0000 |
commit | b7078f351d72f77b0a2b5d1fdf6e050ea0bfef61 (patch) | |
tree | 508f00be0e4066346a9051df41260fb683c9f5c1 | |
parent | 64f6d469667b1bad1f9ac1b45ee90de09f2cc6c2 (diff) | |
download | haskell-b7078f351d72f77b0a2b5d1fdf6e050ea0bfef61.tar.gz |
Fix formatting and wording in documentation of DoRec
-rw-r--r-- | docs/users_guide/glasgow_exts.xml | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 60466911db..f6879febec 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -876,12 +876,11 @@ import Control.Monad.Fix justOnes = do { rec { xs <- Just (1:xs) } ; return (map negate xs) } </programlisting> -The <literal>rec</literal> As you can guess <literal>justOnes</literal> will evaluate to <literal>Just [-1,-1,-1,...</literal>. </para> <para> The background and motivation for recusrive do-notation is described in -<ulink url="http://citeseer.ist.psu.edu/erk02recursive.html">A recursive do for Haskell</ulink>, +<ulink url="http://sites.google.com/site/leventerkok/">A recursive do for Haskell</ulink>, 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, @@ -894,10 +893,24 @@ in the paper. <para> The recursive do-notation is enabled with the flag <option>-XDoRec</option> or, equivalently, the LANGUAGE pragma <option>DoRec</option>. It introduces the single new keyword "<literal>rec</literal>", -which wraps a mutually-recusrive group of monadic statements, -producing a single statement. Similar to a <literal>let</literal> +which wraps a mutually-recursive group of monadic statements, +producing a single statement. +</para> +<para>Similar to a <literal>let</literal> statement, the variables bound in the <literal>rec</literal> are visible throughout the <literal>rec</literal> group, and below it. +For example, compare +<programlisting> +do { a <- getChar do { a <- getChar + ; let { r1 = f a r2 ; rec { r1 <- f a r2 + ; r2 = g r1 } ; r2 <- g r1 } + ; return (r1 ++ r2) } ; return (r1 ++ r2) } +</programlisting> +In both cases, <literal>r1</literal> and <literal>r2</literal> are +available both throughout the <literal>let</literal> or <literal>rec</literal> block, and +in the statements that follow it. The difference is that <literal>let</literal> is non-monadic, +while <literal>rec</literal> is monadic. (In Haskell <literal>let</literal> is +really <literal>letrec</literal>, of course.) </para> <para> The Control.Monad.Fix library introduces the <literal>MonadFix</literal> class. Its definition is: @@ -914,13 +927,12 @@ dictates how the required recursion operation should be performed. For example, justOnes = do { xs <- mfix (\xs' -> do { xs <- Just (1:xs'); return xs }) ; return (map negate xs) } </programlisting> -In general, a <literal>rec</literal> statment <literal>rec <replaceable>ss</replaceable></literal> +In general, the statment <literal>rec <replaceable>ss</replaceable></literal> is desugared to the statement <programlisting> - <replaceable>vs</replaceable> <- mfix (\~<replaceable>vs</replaceable> -> do { <replaceable>ss</replaceable> - ; return <replaceable>vs</replaceable> }) + <replaceable>vs</replaceable> <- mfix (\~<replaceable>vs</replaceable> -> do { <replaceable>ss</replaceable>; return <replaceable>vs</replaceable> }) </programlisting> -where <replaceable>vs</replaceable> is a tuple of the varaibles bound by <replaceable>ss</replaceable>. +where <replaceable>vs</replaceable> is a tuple of the variables bound by <replaceable>ss</replaceable>. Moreover, the original <literal>rec</literal> typechecks exactly when the above desugared version would do so. (For example, this means that the variables <replaceable>vs</replaceable> are all monomorphic in the statements @@ -937,6 +949,9 @@ It is enabled with the flag <literal>-XDoRec</literal>, which is in turn implied <listitem><para> If recursive bindings are required for a monad, then that monad must be declared an instance of the <literal>MonadFix</literal> class. +</para></listitem> + +<listitem><para> The following instances of <literal>MonadFix</literal> 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). @@ -950,16 +965,17 @@ be distinct (Section 3.3 of the paper). <listitem><para> Similar to let-bindings, GHC implements the segmentation technique described in Section 3.2 of -<ulink url="http://citeseer.ist.psu.edu/erk02recursive.html">A recursive do for Haskell</ulink>, -to break up a single <literal>rec</literal> statement into a sequenc e of statements with +<ulink url="http://sites.google.com/site/leventerkok/">A recursive do for Haskell</ulink>, +to break up a single <literal>rec</literal> statement into a sequence of statements with <literal>rec</literal> groups of minimal size. This -improves polymorphism, and reduces the size of the recursive "knot". +improves polymorphism, reduces the size of the recursive "knot", and, as the paper +describes, also has a semantic effect (unless the monad satisfies the right-shrinking law). </para></listitem> </itemizedlist> </para> </sect3> -<sect3> <title Mdo-notation (deprecated) </title> +<sect3> <title> Mdo-notation (deprecated) </title> <para> GHC used to support the flag <option>-XREecursiveDo</option>, which enabled the keyword <literal>mdo</literal>, precisely as described in |