diff options
| author | Simon Peyton Jones <simonpj@microsoft.com> | 2011-04-28 11:44:12 +0100 |
|---|---|---|
| committer | Simon Peyton Jones <simonpj@microsoft.com> | 2011-04-28 11:44:12 +0100 |
| commit | 478e69b303eb2e653a2ebf5c888b5efdfef1fb9d (patch) | |
| tree | d23ca1c0b6dc6a0ab58cc65db055fa9109f5081e /docs/users_guide | |
| parent | 66a733f23eebbd69f6e2d00a9f73c4d5541b5c39 (diff) | |
| download | haskell-478e69b303eb2e653a2ebf5c888b5efdfef1fb9d.tar.gz | |
Preliminary monad-comprehension patch (Trac #4370)
This is the work of Nils Schweinsberg <mail@n-sch.de>
It adds the language extension -XMonadComprehensions, which
generalises list comprehension syntax [ e | x <- xs] to work over
arbitrary monads.
Diffstat (limited to 'docs/users_guide')
| -rw-r--r-- | docs/users_guide/flags.xml | 6 | ||||
| -rw-r--r-- | docs/users_guide/glasgow_exts.xml | 162 |
2 files changed, 168 insertions, 0 deletions
diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml index 26ab9ebe5f..add2f5e1b7 100644 --- a/docs/users_guide/flags.xml +++ b/docs/users_guide/flags.xml @@ -898,6 +898,12 @@ <entry>dynamic</entry> <entry><option>-XNoTransformListComp</option></entry> </row> + <row> + <entry><option>-XMonadComprehensions</option></entry> + <entry>Enable <link linkend="monad-comprehensions">monad comprehensions</link>.</entry> + <entry>dynamic</entry> + <entry><option>-XNoMonadComprehensions</option></entry> + </row> <row> <entry><option>-XUnliftedFFITypes</option></entry> <entry>Enable unlifted FFI types.</entry> diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 9ea3332463..54a4833230 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -1201,6 +1201,168 @@ output = [ x </para> </sect2> + <!-- ===================== MONAD COMPREHENSIONS ===================== --> + +<sect2 id="monad-comprehensions"> + <title>Monad comprehensions</title> + <indexterm><primary>monad comprehensions</primary></indexterm> + + <para> + Monad comprehesions generalise the list comprehension notation to work + for any monad. + </para> + + <para>Monad comprehensions support:</para> + + <itemizedlist> + <listitem> + <para> + Bindings: + </para> + +<programlisting> +[ x + y | x <- Just 1, y <- Just 2 ] +</programlisting> + + <para> + Bindings are translated with the <literal>(>>=)</literal> and + <literal>return</literal> functions to the usual do-notation: + </para> + +<programlisting> +do x <- Just 1 + y <- Just 2 + return (x+y) +</programlisting> + + </listitem> + <listitem> + <para> + Guards: + </para> + +<programlisting> +[ x | x <- [1..10], x <= 5 ] +</programlisting> + + <para> + Guards are translated with the <literal>guard</literal> function, + which requires a <literal>MonadPlus</literal> instance: + </para> + +<programlisting> +do x <- [1..10] + guard (x <= 5) + return x +</programlisting> + + </listitem> + <listitem> + <para> + Transform statements (as with <literal>-XTransformListComp</literal>): + </para> + +<programlisting> +[ x+y | x <- [1..10], y <- [1..x], then take 2 ] +</programlisting> + + <para> + This translates to: + </para> + +<programlisting> +do (x,y) <- take 2 (do x <- [1..10] + y <- [1..x] + return (x,y)) + return (x+y) +</programlisting> + + </listitem> + <listitem> + <para> + Group statements (as with <literal>-XTransformListComp</literal>): + </para> + +<programlisting> +[ x | x <- [1,1,2,2,3], then group by x ] +[ x | x <- [1,1,2,2,3], then group by x using GHC.Exts.groupWith ] +[ x | x <- [1,1,2,2,3], then group using myGroup ] +</programlisting> + + <para> + The basic <literal>then group by e</literal> statement is + translated using the <literal>mgroupWith</literal> function, which + requires a <literal>MonadGroup</literal> instance, defined in + <ulink url="&libraryBaseLocation;/Control-Monad-Group.html"><literal>Control.Monad.Group</literal></ulink>: + </para> + +<programlisting> +do x <- mgroupWith (do x <- [1,1,2,2,3] + return x) + return x +</programlisting> + + <para> + Note that the type of <literal>x</literal> is changed by the + grouping statement. + </para> + + <para> + The grouping function can also be defined with the + <literal>using</literal> keyword. + </para> + + </listitem> + <listitem> + <para> + Parallel statements (as with <literal>-XParallelListComp</literal>): + </para> + +<programlisting> +[ (x+y) | x <- [1..10] + | y <- [11..20] + ] +</programlisting> + + <para> + Parallel statements are translated using the + <literal>mzip</literal> function, which requires a + <literal>MonadZip</literal> instance defined in + <ulink url="&libraryBaseLocation;/Control-Monad-Zip.html"><literal>Control.Monad.Zip</literal></ulink>: + </para> + +<programlisting> +do (x,y) <- mzip (do x <- [1..10] + return x) + (do y <- [11..20] + return y) + return (x+y) +</programlisting> + + </listitem> + </itemizedlist> + + <para> + All these features are enabled by default if the + <literal>MonadComprehensions</literal> extension is enabled. The types + and more detailed examples on how to use comprehensions are explained + in the previous chapters <xref + linkend="generalised-list-comprehensions"/> and <xref + linkend="parallel-list-comprehensions"/>. In general you just have + to replace the type <literal>[a]</literal> with the type + <literal>Monad m => m a</literal> for monad comprehensions. + </para> + + <para> + Note: Even though most of these examples are using the list monad, + monad comprehensions work for any monad. + The <literal>base</literal> package offers all necessary instances for + lists, which make <literal>MonadComprehensions</literal> backward + compatible to built-in, transform and parallel list comprehensions. + </para> + +</sect2> + <!-- ===================== REBINDABLE SYNTAX =================== --> <sect2 id="rebindable-syntax"> |
