From: simonpj@microsoft.com Date: Thu, 29 Oct 2009 11:47:26 +0000 (+0000) Subject: Fix formatting and wording in documentation of DoRec X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=b7078f351d72f77b0a2b5d1fdf6e050ea0bfef61 Fix formatting and wording in documentation of DoRec --- diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 6046691..f6879fe 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) } -The rec 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, +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, @@ -894,10 +893,24 @@ in the paper. 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 +which wraps a mutually-recursive 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. +For example, compare + +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) } + +In both cases, r1 and r2 are +available both throughout the let or rec block, and +in the statements that follow it. The difference is that let is non-monadic, +while rec is monadic. (In Haskell let is +really letrec, of course.) The Control.Monad.Fix library introduces the MonadFix 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) } -In general, a rec statment rec ss +In general, the statment rec ss is desugared to the statement - vs <- mfix (\~vs -> do { ss - ; return vs }) + vs <- mfix (\~vs -> do { ss; return vs }) -where vs is a tuple of the varaibles bound by ss. +where vs is a tuple of the variables 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 @@ -937,6 +949,9 @@ It is enabled with the flag -XDoRec, which is in turn implied 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). @@ -950,16 +965,17 @@ be distinct (Section 3.3 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 +A recursive do for Haskell, +to break up a single rec statement into a sequence of statements with rec 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). - +<sect3> <title> Mdo-notation (deprecated) GHC used to support the flag , which enabled the keyword mdo, precisely as described in