packages feed

polyparse-1.0: docs/haddock/src/Text/Parse.html

<pre><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>Parse
  <font color=Cyan>(</font> <font color=Blue>-- * The Parse class is a replacement for the standard Read class. </font>
    <font color=Blue>-- $parser</font>
    TextParser	<font color=Blue>-- synonym for Parser Char, i.e. string input, no state</font>
  <font color=Cyan>,</font> Parse<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font>	<font color=Blue>-- instances: (), (a,b), (a,b,c), Maybe a, Either a, [a],</font>
		<font color=Blue>--            Int, Integer, Float, Double, Char, Bool</font>
  <font color=Cyan>,</font> parseByRead	<font color=Blue>-- :: Read a =&gt; String -&gt; TextParser a</font>
    <font color=Blue>-- ** Combinators specific to string input, lexed haskell-style</font>
  <font color=Cyan>,</font> word	<font color=Blue>-- :: TextParser String</font>
  <font color=Cyan>,</font> isWord	<font color=Blue>-- :: String -&gt; TextParser ()</font>
  <font color=Cyan>,</font> optionalParens	<font color=Blue>-- :: TextParser a -&gt; TextParser a</font>
  <font color=Cyan>,</font> field	<font color=Blue>-- :: Parse a =&gt; String -&gt; TextParser a</font>
  <font color=Cyan>,</font> constructors<font color=Blue>-- :: [(String,TextParser a)] -&gt; TextParser a</font>
  <font color=Cyan>,</font> enumeration <font color=Blue>-- :: Show a =&gt; String -&gt; [a] -&gt; TextParser a</font>
    <font color=Blue>-- ** Re-export all the more general combinators from Poly too</font>
  <font color=Cyan>,</font> <font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly
  <font color=Cyan>)</font> <font color=Green><u>where</u></font>

<font color=Green><u>import</u></font> Char <font color=Cyan>(</font>isSpace<font color=Cyan>)</font>
<font color=Green><u>import</u></font> List <font color=Cyan>(</font>intersperse<font color=Cyan>)</font>
<font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly

<font color=Blue>------------------------------------------------------------------------</font>
<font color=Blue>-- $parser</font>
<font color=Blue>-- The Parse class is a replacement for the standard Read class.  It is a</font>
<font color=Blue>-- specialisation of the (poly) Parser monad for String input.</font>
<font color=Blue>-- There are instances defined for all Prelude types.</font>
<font color=Blue>-- For user-defined types, you can write your own instance, or use</font>
<font color=Blue>-- DrIFT to generate them automatically, e.g. {-! derive : Parse !-}</font>

<font color=Blue>-- | A synonym for Parser Char, i.e. string input (no state)</font>
<a name="TextParser"></a><font color=Green><u>type</u></font> TextParser a <font color=Red>=</font> Parser Char a

<font color=Blue>-- | The class @Parse@ is a replacement for @Read@, operating over String input.</font>
<font color=Blue>--   Essentially, it permits better error messages for why something failed to</font>
<font color=Blue>--   parse.  It is rather important that @parse@ can read back exactly what</font>
<font color=Blue>--   is generated by the corresponding instance of @show@.  To apply a parser</font>
<font color=Blue>--   to some text, use @runParser@.</font>
<a name="Parse"></a><font color=Green><u>class</u></font> Parse a <font color=Green><u>where</u></font>
    parse     <font color=Red>::</font> TextParser a
    parseList <font color=Red>::</font> TextParser <font color=Red>[</font>a<font color=Red>]</font>	<font color=Blue>-- only to distinguish [] and ""</font>
    parseList  <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"[]"</font><font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>
                   <font color=Cyan>`onFail`</font>
                 <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"["</font><font color=Cyan>;</font> isWord <font color=Magenta>"]"</font><font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>
                   <font color=Cyan>`onFail`</font>
                 bracketSep <font color=Cyan>(</font>isWord <font color=Magenta>"["</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>","</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>"]"</font><font color=Cyan>)</font> parse
                   <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Expected a list, but\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>

<font color=Blue>-- | If there already exists a Read instance for a type, then we can make</font>
<font color=Blue>--   a Parser for it, but with only poor error-reporting.</font>
parseByRead <font color=Red>::</font> Read a <font color=Red>=&gt;</font> String <font color=Red>-&gt;</font> TextParser a
<a name="parseByRead"></a>parseByRead name <font color=Red>=</font>
    P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> reads s <font color=Green><u>of</u></font>
                <font color=Red>[</font><font color=Red>]</font>       <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no parse, expected a "</font><font color=Cyan>++</font>name<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>
                <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Right a<font color=Cyan>,</font> s'<font color=Cyan>)</font>
                <font color=Green><u>_</u></font>        <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"ambiguous parse, expected a "</font><font color=Cyan>++</font>name<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>
      <font color=Cyan>)</font>

<font color=Blue>-- | One lexical chunk (Haskell-style lexing).</font>
word <font color=Red>::</font> TextParser String
<a name="word"></a>word <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> lex s <font color=Green><u>of</u></font>
                   <font color=Red>[</font><font color=Red>]</font>         <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input? (impossible)"</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>
                   <font color=Red>[</font><font color=Cyan>(</font><font color=Magenta>""</font><font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red>]</font>  <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input?"</font><font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>)</font>
                   <font color=Cyan>(</font><font color=Cyan>(</font>x<font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<font color=Cyan>)</font> <font color=Cyan>)</font>

<font color=Blue>-- | Ensure that the next input word is the given string.  (Note the input</font>
<font color=Blue>--   is lexed as haskell, so wordbreaks at spaces, symbols, etc.)</font>
isWord <font color=Red>::</font> String <font color=Red>-&gt;</font> TextParser String
<a name="isWord"></a>isWord w <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> w' <font color=Red>&lt;-</font> word
              <font color=Cyan>;</font> <font color=Green><u>if</u></font> w'<font color=Cyan>==</font>w <font color=Green><u>then</u></font> return w <font color=Green><u>else</u></font> fail <font color=Cyan>(</font><font color=Magenta>"expected "</font><font color=Cyan>++</font>w<font color=Cyan>++</font><font color=Magenta>" got "</font><font color=Cyan>++</font>w'<font color=Cyan>)</font>
              <font color=Cyan>}</font>

<font color=Blue>-- | Allow true string parens around an item.</font>
optionalParens <font color=Red>::</font> TextParser a <font color=Red>-&gt;</font> TextParser a
<a name="optionalParens"></a>optionalParens p <font color=Red>=</font> bracket <font color=Cyan>(</font>isWord <font color=Magenta>"("</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>")"</font><font color=Cyan>)</font> p <font color=Cyan>`onFail`</font> p

<font color=Blue>-- | Deal with named field syntax.  The string argument is the field name,</font>
<font color=Blue>--   and the parser returns the value of the field.</font>
field <font color=Red>::</font> Parse a <font color=Red>=&gt;</font> String <font color=Red>-&gt;</font> TextParser a
<a name="field"></a>field name <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord name<font color=Cyan>;</font> commit <font color=Cyan>$</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"="</font><font color=Cyan>;</font> parse <font color=Cyan>}</font> <font color=Cyan>}</font>

<font color=Blue>-- | Parse one of a bunch of alternative constructors.  In the list argument,</font>
<font color=Blue>--   the first element of the pair is the constructor name, and</font>
<font color=Blue>--   the second is the parser for the rest of the value.  The first matching</font>
<font color=Blue>--   parse is returned.</font>
constructors <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font>TextParser a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-&gt;</font> TextParser a
<a name="constructors"></a>constructors cs <font color=Red>=</font> oneOf' <font color=Cyan>(</font>map cons cs<font color=Cyan>)</font>
    <font color=Green><u>where</u></font> cons <font color=Cyan>(</font>name<font color=Cyan>,</font>p<font color=Cyan>)</font> <font color=Red>=</font>
               <font color=Cyan>(</font> name
               <font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord name
                    <font color=Cyan>;</font> p <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"got constructor, but within "</font>
                                        <font color=Cyan>++</font>name<font color=Cyan>++</font><font color=Magenta>",\n"</font><font color=Cyan>)</font><font color=Cyan>++</font><font color=Cyan>)</font>
                    <font color=Cyan>}</font>
               <font color=Cyan>)</font>

<font color=Blue>-- | Parse one of the given nullary constructors (an enumeration).</font>
<font color=Blue>--   The string argument is the name of the type, and the list argument</font>
<font color=Blue>--   should contain all of the possible enumeration values.</font>
enumeration <font color=Red>::</font> <font color=Cyan>(</font>Show a<font color=Cyan>)</font> <font color=Red>=&gt;</font> String <font color=Red>-&gt;</font> <font color=Red>[</font>a<font color=Red>]</font> <font color=Red>-&gt;</font> TextParser a
<a name="enumeration"></a>enumeration typ cs <font color=Red>=</font> oneOf <font color=Cyan>(</font>map <font color=Cyan>(</font><font color=Red>\</font>c<font color=Red>-&gt;</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Cyan>(</font>show c<font color=Cyan>)</font><font color=Cyan>;</font> return c <font color=Cyan>}</font><font color=Cyan>)</font> cs<font color=Cyan>)</font>
                         <font color=Cyan>`adjustErr`</font>
                     <font color=Cyan>(</font><font color=Cyan>++</font><font color=Cyan>(</font><font color=Magenta>"\n  expected "</font><font color=Cyan>++</font>typ<font color=Cyan>++</font><font color=Magenta>" value ("</font><font color=Cyan>++</font>e<font color=Cyan>++</font><font color=Magenta>")"</font><font color=Cyan>)</font><font color=Cyan>)</font>
    <font color=Green><u>where</u></font> e <font color=Red>=</font> concat <font color=Cyan>(</font>intersperse <font color=Magenta>", "</font> <font color=Cyan>(</font>map show <font color=Cyan>(</font>init cs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>
              <font color=Cyan>++</font> <font color=Magenta>", or "</font> <font color=Cyan>++</font> show <font color=Cyan>(</font>last cs<font color=Cyan>)</font>

<font color=Blue>------------------------------------------------------------------------</font>
<font color=Blue>-- Instances for all the Standard Prelude types.</font>

<font color=Blue>-- Basic types</font>
<font color=Green><u>instance</u></font> Parse Int <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> parseByRead <font color=Magenta>"Int"</font>
<font color=Green><u>instance</u></font> Parse Integer <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> parseByRead <font color=Magenta>"Integer"</font>
<font color=Green><u>instance</u></font> Parse Float <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> parseByRead <font color=Magenta>"Float"</font>
<font color=Green><u>instance</u></font> Parse Double <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> parseByRead <font color=Magenta>"Double"</font>
<font color=Green><u>instance</u></font> Parse Char <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> parseByRead <font color=Magenta>"Char"</font>
 <font color=Blue>-- parseList = bracket (isWord "\"") (satisfy (=='"'))</font>
 <font color=Blue>--                     (many (satisfy (/='"')))</font>
	<font color=Blue>-- not totally correct for strings...</font>
    parseList <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> w <font color=Red>&lt;-</font> word<font color=Cyan>;</font> <font color=Green><u>if</u></font> head w <font color=Cyan>==</font> <font color=Magenta>'"'</font> <font color=Green><u>then</u></font> return <font color=Cyan>(</font>init <font color=Cyan>(</font>tail w<font color=Cyan>)</font><font color=Cyan>)</font>
                                <font color=Green><u>else</u></font> fail <font color=Magenta>"not a string"</font> <font color=Cyan>}</font>

<font color=Green><u>instance</u></font> Parse Bool <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> enumeration <font color=Magenta>"Bool"</font> <font color=Red>[</font>False<font color=Cyan>,</font>True<font color=Red>]</font>

<font color=Green><u>instance</u></font> Parse Ordering <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> enumeration <font color=Magenta>"Ordering"</font> <font color=Red>[</font>LT<font color=Cyan>,</font>EQ<font color=Cyan>,</font>GT<font color=Red>]</font>

<font color=Blue>-- Structural types</font>
<font color=Green><u>instance</u></font> Parse <font color=Cyan>(</font><font color=Cyan>)</font> <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> P p
      <font color=Green><u>where</u></font> p <font color=Red>[</font><font color=Red>]</font>       <font color=Red>=</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input: expected a ()"</font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>
            p <font color=Cyan>(</font><font color=Magenta>'('</font><font color=Red><b>:</b></font>cs<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>case</u></font> dropWhile isSpace cs <font color=Green><u>of</u></font>
                             <font color=Cyan>(</font><font color=Magenta>')'</font><font color=Red><b>:</b></font>s<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Right <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>
                             <font color=Green><u>_</u></font>       <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Expected ) after ("</font><font color=Cyan>)</font><font color=Cyan>,</font> cs<font color=Cyan>)</font>
            p <font color=Cyan>(</font>c<font color=Red><b>:</b></font>cs<font color=Cyan>)</font> <font color=Red>|</font> isSpace c <font color=Red>=</font> p cs
                     <font color=Red>|</font> otherwise <font color=Red>=</font> <font color=Cyan>(</font> Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Expected a (), got "</font><font color=Cyan>++</font>show c<font color=Cyan>)</font>
                                     <font color=Cyan>,</font> <font color=Cyan>(</font>c<font color=Red><b>:</b></font>cs<font color=Cyan>)</font><font color=Cyan>)</font>

<font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>)</font> <font color=Red>=&gt;</font> Parse <font color=Cyan>(</font>a<font color=Cyan>,</font>b<font color=Cyan>)</font> <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> isWord <font color=Magenta>"("</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Opening a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> x <font color=Red>&lt;-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 1st item of a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> y <font color=Red>&lt;-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 2nd item of a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> isWord <font color=Magenta>")"</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Closing a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Cyan>,</font>y<font color=Cyan>)</font> <font color=Cyan>}</font>

<font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>,</font> Parse c<font color=Cyan>)</font> <font color=Red>=&gt;</font> Parse <font color=Cyan>(</font>a<font color=Cyan>,</font>b<font color=Cyan>,</font>c<font color=Cyan>)</font> <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> isWord <font color=Magenta>"("</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Opening a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> x <font color=Red>&lt;-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 1st item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating(1) a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> y <font color=Red>&lt;-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 2nd item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating(2) a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> z <font color=Red>&lt;-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 3rd item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> isWord <font color=Magenta>")"</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Closing a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>
              <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Cyan>,</font>y<font color=Cyan>,</font>z<font color=Cyan>)</font> <font color=Cyan>}</font>

<font color=Green><u>instance</u></font> Parse a <font color=Red>=&gt;</font> Parse <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font> <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"Nothing"</font><font color=Cyan>;</font> return Nothing <font color=Cyan>}</font>
              <font color=Cyan>`onFail`</font>
            <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"Just"</font>
               <font color=Cyan>;</font> fmap Just <font color=Cyan>$</font> optionalParens parse
                     <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"but within Just, "</font><font color=Cyan>++</font><font color=Cyan>)</font>
               <font color=Cyan>}</font>
              <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"expected a Maybe (Just or Nothing)\n"</font><font color=Cyan>++</font><font color=Cyan>)</font><font color=Cyan>.</font>indent <font color=Magenta>2</font><font color=Cyan>)</font>

<font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>)</font> <font color=Red>=&gt;</font> Parse <font color=Cyan>(</font>Either a b<font color=Cyan>)</font> <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> constructors <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"Left"</font><font color=Cyan>,</font>  <font color=Green><u>do</u></font> <font color=Cyan>{</font> fmap Left  <font color=Cyan>$</font> optionalParens parse <font color=Cyan>}</font> <font color=Cyan>)</font>
                         <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"Right"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> fmap Right <font color=Cyan>$</font> optionalParens parse <font color=Cyan>}</font> <font color=Cyan>)</font>
                         <font color=Red>]</font>

<font color=Green><u>instance</u></font> Parse a <font color=Red>=&gt;</font> Parse <font color=Red>[</font>a<font color=Red>]</font> <font color=Green><u>where</u></font>
    parse <font color=Red>=</font> parseList

<font color=Blue>------------------------------------------------------------------------</font>
</pre>