Source

fparsec / Doc / html / users-guide / applying-parsers-in-sequence.html

Full commit
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title>Applying parsers in sequence</title>
 <link rel="stylesheet" type="text/css" media="all" href="../css/style.css" />
 <link rel="stylesheet" type="text/css" media="screen" href="../css/screen-sidebar.css" />
 <!--[if lt IE 9]>
 <link rel="stylesheet" type="text/css" media="all" href="../css/style-ie.css" />
 <![endif]-->
 <!--[if IE 6]>
 <link rel="stylesheet" type="text/css" media="all" href="../css/style-ie6.css" />
 <![endif]-->
 <link rel="stylesheet" type="text/css" media="print" href="../css/print.css" />
</head>
<body>
 <div id="fixed-layer">
 <div id="fixed-wrapper">
 <div id="sidebar">
  <div id="top-links"><span><a href="http://bitbucket.org/fparsec/main">FParsec @ BitBucket</a> | <a href="https://bitbucket.org/fparsec/main/issues">Report a bug</a> | <a href="mailto:fparsec [at] quanttec.com?subject=FParsec&amp;body=Hello Stephan,%0A%0A[your feedback]">Feedback</a></span></div>
  <div id="nav-tree">
   <table class="nav n1">
    <tbody class="nav-open n1">
     <tr class="nav-entry n1 _1">
      <td class="nav-number n1"></td>
      <td class="nav-title n1"><a href="../index.html">FParsec Documentation</a></td>
     </tr>
     <tr class="nav-subentries n1 _1">
      <td class="nav-subentries-number n1"></td>
      <td class="nav-subentries n1">
       <table class="nav n2">
        <tbody class="nav-before-open n2">
         <tr class="nav-entry n2 _1">
          <td class="nav-number n2"><a href="../about/index.html"><span class="section-number">1</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../about/index.html">About FParsec</a></td>
         </tr>
         <tr class="nav-entry n2 _2">
          <td class="nav-number n2"><a href="../license.html"><span class="section-number">2</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../license.html">License</a></td>
         </tr>
         <tr class="nav-entry n2 _3">
          <td class="nav-number n2">
           <a href="../download-and-installation.html"><span class="section-number">3</span><span class="nav-space"></span></a>
          </td>
          <td class="nav-title n2"><a href="../download-and-installation.html">Download and installation</a></td>
         </tr>
         <tr class="nav-entry n2 _4">
          <td class="nav-number n2"><a href="../tutorial.html"><span class="section-number">4</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../tutorial.html">Tutorial</a></td>
         </tr>
        </tbody>
        <tbody class="nav-open n2">
         <tr class="nav-entry n2 _5">
          <td class="nav-number n2"><a href="index.html"><span class="section-number">5</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="index.html">User’s Guide</a></td>
         </tr>
         <tr class="nav-subentries n2 _5">
          <td class="nav-subentries-number n2"></td>
          <td class="nav-subentries n2">
           <table class="nav n3">
            <tbody class="nav-before-open n3">
             <tr class="nav-entry n3 _1">
              <td class="nav-number n3"><a href="parser-functions.html"><span class="section-number">1</span><span class="nav-space"></span></a></td>
              <td class="nav-title n3"><a href="parser-functions.html">Parser functions</a></td>
             </tr>
             <tr class="nav-entry n3 _2">
              <td class="nav-number n3">
               <a href="running-parsers-on-input.html"><span class="section-number">2</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="running-parsers-on-input.html">Running parsers on input</a></td>
             </tr>
             <tr class="nav-entry n3 _3">
              <td class="nav-number n3">
               <a href="internals-of-a-simple-parser-function.html"><span class="section-number">3</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3">
               <a href="internals-of-a-simple-parser-function.html">Internals of a simple <code class="fsharp"><span class="ci">Parser</span></code>
               function</a>
              </td>
             </tr>
            </tbody>
            <tbody class="nav-open selected n3">
             <tr class="nav-entry selected n3 _4">
              <td class="nav-number selected n3"><a href="#"><span class="section-number">4</span><span class="nav-space"></span></a></td>
              <td class="nav-title selected n3"><a href="#">Applying parsers in sequence</a></td>
             </tr>
             <tr class="nav-subentries selected n3 _4">
              <td class="nav-subentries-number selected n3"></td>
              <td class="nav-subentries selected n3">
               <table class="nav n4">
                <tbody class="nav-before-open n4">
                 <tr class="nav-entry n4 _1">
                  <td class="nav-number n4"><a href="#the-definition-of"><span class="section-number">1</span><span class="nav-space"></span></a></td>
                  <td class="nav-title n4">
                   <a href="#the-definition-of">The definition of <code class="fsharp"><span class="co">&gt;&gt;.</span></code></a>
                  </td>
                 </tr>
                 <tr class="nav-entry n4 _2">
                  <td class="nav-number n4">
                   <a href="#merging-error-messages"><span class="section-number">2</span><span class="nav-space"></span></a>
                  </td>
                  <td class="nav-title n4"><a href="#merging-error-messages">Merging error messages</a></td>
                 </tr>
                 <tr class="nav-entry n4 _3">
                  <td class="nav-number n4"><a href="#the-statetag"><span class="section-number">3</span><span class="nav-space"></span></a></td>
                  <td class="nav-title n4"><a href="#the-statetag">The <code class="fsharp"><span class="ci">StateTag</span></code></a></td>
                 </tr>
                 <tr class="nav-entry n4 _4">
                  <td class="nav-number n4"><a href="#generalizing"><span class="section-number">4</span><span class="nav-space"></span></a></td>
                  <td class="nav-title n4"><a href="#generalizing">Generalizing <code class="fsharp"><span class="co">&gt;&gt;.</span></code></a></td>
                 </tr>
                 <tr class="nav-entry n4 _5">
                  <td class="nav-number n4"><a href="#the-combinator"><span class="section-number">5</span><span class="nav-space"></span></a></td>
                  <td class="nav-title n4">
                   <a href="#the-combinator">The <code class="fsharp"><span class="co">&gt;&gt;=</span></code> combinator</a>
                  </td>
                 </tr>
                </tbody>
               </table>
              </td>
             </tr>
            </tbody>
            <tbody class="nav-after-open n3">
             <tr class="nav-entry n3 _5">
              <td class="nav-number n3"><a href="parsing-sequences.html"><span class="section-number">5</span><span class="nav-space"></span></a></td>
              <td class="nav-title n3"><a href="parsing-sequences.html">Parsing sequences</a></td>
             </tr>
             <tr class="nav-entry n3 _6">
              <td class="nav-number n3">
               <a href="parsing-alternatives.html"><span class="section-number">6</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="parsing-alternatives.html">Parsing alternatives</a></td>
             </tr>
             <tr class="nav-entry n3 _7">
              <td class="nav-number n3">
               <a href="looking-ahead-and-backtracking.html"><span class="section-number">7</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="looking-ahead-and-backtracking.html">Looking ahead and backtracking</a></td>
             </tr>
             <tr class="nav-entry n3 _8">
              <td class="nav-number n3">
               <a href="customizing-error-messages.html"><span class="section-number">8</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="customizing-error-messages.html">Customizing error messages</a></td>
             </tr>
             <tr class="nav-entry n3 _9">
              <td class="nav-number n3">
               <a href="parsing-with-user-state.html"><span class="section-number">9</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="parsing-with-user-state.html">Parsing with user state</a></td>
             </tr>
             <tr class="nav-entry n3 _0">
              <td class="nav-number n3">
               <a href="where-is-the-monad.html"><span class="section-number">10</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="where-is-the-monad.html">Where is the monad?</a></td>
             </tr>
             <tr class="nav-entry n3 _1">
              <td class="nav-number n3">
               <a href="debugging-a-parser.html"><span class="section-number">11</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="debugging-a-parser.html">Debugging a parser</a></td>
             </tr>
             <tr class="nav-entry n3 _2">
              <td class="nav-number n3">
               <a href="performance-optimizations.html"><span class="section-number">12</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="performance-optimizations.html">Performance optimizations</a></td>
             </tr>
             <tr class="nav-entry n3 _3">
              <td class="nav-number n3"><a href="tips-and-tricks.html"><span class="section-number">13</span><span class="nav-space"></span></a></td>
              <td class="nav-title n3"><a href="tips-and-tricks.html">Tips and tricks</a></td>
             </tr>
            </tbody>
           </table>
          </td>
         </tr>
        </tbody>
        <tbody class="nav-after-open n2">
         <tr class="nav-entry n2 _6">
          <td class="nav-number n2"><a href="../reference/index.html"><span class="section-number">6</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../reference/index.html">Reference</a></td>
         </tr>
        </tbody>
       </table>
      </td>
     </tr>
    </tbody>
   </table>
  </div>
  <div id="copyright">
    <span>Copyright © 2012 <a href="../about/contact.html">Stephan Tolksdorf</a></span>
  </div>
 </div>
 </div>
 </div>
 <div id="wrapper">
 <div id="main">
 <div id="main-content">
 <div id="breadcrumbs">
  <span class="breadcrumbs">
   <span id="breadcrumbs-parents"><a href="../index.html">FParsec Documentation</a><span class="breadcrumbs-sep"> > </span><a href="index.html">User’s Guide</a></span><span class="breadcrumbs-sep"> > </span>Applying parsers in sequence
  </span>
 </div>
 <div class="section s2">
  <h1 class="title h2"><span><span class="section-number">5.4</span> Applying parsers in sequence</span></h1>
  <div class="intro i2">
   <div class="para _1">
    <p>
     Now that we have discussed how <code class="fsharp"><a href="../reference/primitives.html#members.Parser"><span
     class="ci">Parser</span></a></code> functions work, we can start explaining how FParsec’s parser combinators work.
    </p>
   </div>
   <div class="para _2">
    <p>
     In this chapter we will discuss combinators that allow you to apply multiple parsers in sequence, i.e. parse the beginning of the input with the
     first parser, then parse the following input with the second parser, and so on.
    </p>
   </div>
  </div>
  <div id="the-definition-of" class="section s3">
   <h2 class="title h3">
    <span><span class="section-number">5.4.1</span> The definition of <code class="fsharp"><a
    href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a></code></span>
   </h2>
   <div class="intro i3">
    <div class="para _1 lcinp">
     <p>The simplest combinators for sequentially applying two parsers are</p>
<pre class="code fsharp"><span class="ck">val</span> <span class="cp">(</span><a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a><span class="cp">)</span><span class="cp">:</span>   <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
<span class="ck">val</span> <span class="cp">(</span><a href="../reference/primitives.html#members...:62::62:"><span class="co">.&gt;&gt;</span></a><span class="cp">)</span><span class="cp">:</span>   <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
</pre>
    </div>
    <div class="para _2">
     <p>
      Both operators take two parsers as arguments and return a combined parser that applies the two parsers in sequence. As you can infer from the
      type signatures, <code class="fsharp"><span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62:.."><span
      class="co">&gt;&gt;.</span></a> <span class="ci">p2</span></code> returns the result of <code class="fsharp"><span class="ci">p2</span></code>
      and <code class="fsharp"><span class="ci">p1</span> <a href="../reference/primitives.html#members...:62::62:"><span
      class="co">.&gt;&gt;</span></a> <span class="ci">p2</span></code> the result of <code class="fsharp"><span class="ci">p1</span></code>. In each
      case the point points to the parser whose result is returned.
     </p>
    </div>
    <div class="para _3 lcinp">
     <p>
      In order to explain exactly what it means to apply two parser in sequence, we give a full definition of the <code class="fsharp"><a
      href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a></code> operator:
     </p>
<pre class="code fsharp"><span class="ck">let</span> <span class="cp">(</span><span class="co">&gt;&gt;.</span><span class="cp">)</span> <span class="cp">(</span><span class="ci">p1</span><span class="cp">:</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">)</span> <span class="cp">(</span><span class="ci">p2</span><span class="cp">:</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">)</span> <span class="cp">=</span>
    <span class="ck">fun</span> <span class="ci">stream</span> <span class="cr">-&gt;</span>
        <span class="ck">let</span> <span class="ci">reply1</span> <span class="cp">=</span> <span class="ci">p1</span> <span class="ci">stream</span>
        <span class="ck">if</span> <span class="ci">reply1</span><span class="cm">.</span><a href="../reference/reply.html#members.Status"><span class="ci">Status</span></a> <span class="co">=</span> <a href="../reference/primitives.html#members.Ok"><span class="ci">Ok</span></a> <span class="ck">then</span>
            <span class="ck">let</span> <span class="ci">stateTag</span> <span class="cp">=</span> <span class="ci">stream</span><span class="cm">.</span><a href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a>
            <span class="ck">let</span> <span class="ck">mutable</span> <span class="ci">reply2</span> <span class="cp">=</span> <span class="ci">p2</span> <span class="ci">stream</span>
            <span class="ck">if</span> <span class="ci">stateTag</span> <span class="co">=</span> <span class="ci">stream</span><span class="cm">.</span><a href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a> <span class="ck">then</span>                        <span class="clc"><span class="cld">//</span> (1)</span>
                <span class="ci">reply2</span><span class="cm">.</span><a href="../reference/reply.html#members.Error"><span class="ci">Error</span></a> <span class="co">&lt;-</span> <a href="../reference/error.html#members.mergeErrors"><span class="ci">mergeErrors</span></a> <span class="ci">reply1</span><span class="cm">.</span><a href="../reference/reply.html#members.Error"><span class="ci">Error</span></a> <span class="ci">reply2</span><span class="cm">.</span><a href="../reference/reply.html#members.Error"><span class="ci">Error</span></a> <span class="clc"><span class="cld">//</span> (2)</span>
            <span class="ci">reply2</span>
        <span class="ck">else</span> <span class="clc"><span class="cld">//</span> reconstruct error reply with new result type</span>
            <a href="../reference/reply.html"><span class="ci">Reply</span></a><span class="cp">(</span><span class="ci">reply1</span><span class="cm">.</span><a href="../reference/reply.html#members.Status"><span class="ci">Status</span></a><span class="cp">,</span> <span class="ci">reply1</span><span class="cm">.</span><a href="../reference/reply.html#members.Error"><span class="ci">Error</span></a><span class="cp">)</span>
</pre>
    </div>
    <div class="para _4">
     <p>
      The implementation of <code class="fsharp"><span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62:.."><span
      class="co">&gt;&gt;.</span></a> <span class="ci">p2</span></code> should be quite self‐explanatory: First <code class="fsharp"><span
      class="ci">p1</span></code> is applied to the input <code class="fsharp"><span class="ci">stream</span></code>. If <code class="fsharp"><span
      class="ci">p1</span></code> succeeds, i.e. if the status of <code class="fsharp"><span class="ci">reply1</span></code> is <code
      class="fsharp"><a href="../reference/primitives.html#members.Ok"><span class="ci">Ok</span></a></code>, <code class="fsharp"><span
      class="ci">p2</span></code> is applied to stream and the reply of <code class="fsharp"><span class="ci">p2</span></code> then becomes the reply
      of the combined parser. However, if <code class="fsharp"><span class="ci">p1</span></code> fails, its reply is immediately propagated as the
      reply of the combined parser. Since <code class="fsharp"><span class="ci">reply1</span></code> has type <code class="fsharp"><a
      href="../reference/reply.html"><span class="ci">Reply</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span
      class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span></code> but <code class="fsharp"><span class="ci">p1</span> <a
      href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <span class="ci">p2</span></code> needs to return a
      <code class="fsharp"><a href="../reference/reply.html"><span class="ci">Reply</span></a><span class="cp">&lt;</span><span
      class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span></code>, the error reply needs to be
      reconstructed with a new result type before it can be returned.
     </p>
    </div>
   </div>
  </div>
  <div id="merging-error-messages" class="section s3">
   <h2 class="title h3"><span><span class="section-number">5.4.2</span> Merging error messages</span></h2>
   <div class="intro i3">
    <div class="para _1">
     <p>
      We mentioned earlier that the error messages returned in the <code class="fsharp"><a href="../reference/reply.html"><span
      class="ci">Reply</span></a><span class="cm">.</span><a href="../reference/reply.html#members.Error"><span class="ci">Error</span></a></code>
      field implicitly refer to the state of the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span
      class="ci">CharStream</span></a></code> at the time the parser returns. In particular the error messages refer to the then current <em>stream
      position</em>. Since the messages do not contain themselves a separate record of the error position they can only be interpreted together with
      the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code> state.
     </p>
    </div>
    <div class="para _2">
     <p>
      When <code class="fsharp"><span class="ci">p2</span></code> does not change the parser state, the error messages from both replies refer to the
      state of the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code> as it is when
      <code class="fsharp"><span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62:.."><span
      class="co">&gt;&gt;.</span></a> <span class="ci">p2</span></code> returns. Thus, the combinator needs to merge the (immutable) <code
      class="fsharp"><a href="../reference/errormessagelist.html"><span class="ci">ErrorMessageList</span></a></code>s from both replies, so that the
      returned list contains all the relevant error messages (see the line marked with <code class="fsharp"><span class="cp">(</span><span
      class="cn">2</span><span class="cp">)</span></code>).
     </p>
    </div>
    <div class="para _3">
     <p>
      In order to check whether the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span
      class="ci">CharStream</span></a></code> state has changed, the combinator does not compare the full states from before and after <code
      class="fsharp"><span class="ci">p2</span></code> is invoked. Instead it only compares the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code> values (see line <code
      class="fsharp"><span class="cp">(</span><span class="cn">1</span><span class="cp">)</span></code>). This improves performance and — for most
      practical purpose — is almost equivalent to comparing the full state, as we will discuss below.
     </p>
    </div>
    <div class="para _4 lcinp">
     <div class="admonition">
      <div class="admonition-title">Note</div>
      <div class="admonition-body">
       <div class="para _1">
        <p>
         The way <code class="fsharp"><span class="cp">(</span><span class="co">&gt;&gt;.</span><span class="cp">)</span></code> handles errors and
         merges error messages is a template for all combinators in FParsec that perform multiple sequential parser invocations.
        </p>
       </div>
      </div>
     </div>
    </div>
    <div class="para _5">
     <p>
      You may wonder why the error messages get merged even though <code class="fsharp"><span class="ci">p1</span></code> succeeded. The somewhat
      counterintuitive reason is that parsers can return nonempty error message lists even when they don’t fail. For example, a parser that skips over
      the <em>optional</em> string <code class="fsharp"><span class="cs"><span class="cld">"</span>str<span class="crd">"</span></span></code> will
      return <code class="fsharp"><a href="../reference/reply.html"><span class="ci">Reply</span></a><span class="cp">(</span><a
      href="../reference/primitives.html#members.Ok"><span class="ci">Ok</span></a><span class="cp">,</span> <span class="cp">()</span><span
      class="cp">,</span> <span class="ci">expectedString</span> <span class="cs"><span class="cld">"</span>str<span class="crd">"</span></span><span
      class="cp">)</span></code> if it doesn’t find the string in the input. In this case the error message describes what further input the parser
      could have parsed at the current stream position. If subsequently a parser fails at the same position, all error messages for the same position
      can be aggregated to give the user as much information as possible about what went wrong and what alternative inputs could have been parsed at
      the given position.
     </p>
    </div>
    <div class="para _6">
     <p>The following sample demonstrates the helpful effect of this error handling behaviour:</p>
<pre class="code fsharp"><span class="ck">let</span> <span class="ci">str</span> <span class="ci">s</span> <span class="cp">=</span> <a href="../reference/charparsers.html#members.pstring"><span class="ci">pstring</span></a> <span class="ci">s</span>

<span class="ck">let</span> <span class="ci">oneOrTwoInts</span> <span class="cp">=</span>
    <span class="ci">str</span> <span class="cs"><span class="cld">"</span>(<span class="crd">"</span></span> <a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <a href="../reference/primitives.html#members.tuple2"><span class="ci">tuple2</span></a> <a href="../reference/charparsers.html#members.pint32"><span class="ci">pint32</span></a> <span class="cp">(</span><a href="../reference/primitives.html#members.opt"><span class="ci">opt</span></a> <span class="cp">(</span><span class="ci">str</span> <span class="cs"><span class="cld">"</span>,<span class="crd">"</span></span> <a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <a href="../reference/charparsers.html#members.spaces"><span class="ci">spaces</span></a> <a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <a href="../reference/charparsers.html#members.pint32"><span class="ci">pint32</span></a><span class="cp">)</span><span class="cp">)</span> <a href="../reference/primitives.html#members...:62::62:"><span class="co">.&gt;&gt;</span></a> <span class="ci">str</span> <span class="cs"><span class="cld">"</span>)<span class="crd">"</span></span>
</pre>
<pre class="code fsharp"><span class="cmd"><span class="cmdp">&gt;</span> <a href="../reference/charparsers.html#members.run"><span class="ci">run</span></a> <span class="ci">oneOrTwoInts</span> <span class="cs"><span class="cld">"</span>(1 2)<span class="crd">"</span></span><span class="cp">;;</span></span>
<span class="cout">val it : ParserResult&lt;(int32 * int32 option),unit&gt; = Failure:
Error in Ln: 1 Col: 3
(1 2)
  ^
Expecting: ')' or ','
</span></pre>
     <p>
      This error message wouldn’t mention the possibility of a missing comma if the <code class="fsharp"><a
      href="../reference/primitives.html#members...:62::62:"><span class="co">.&gt;&gt;</span></a></code> combinator did not merge error messages for
      the same position when the left‐hand side parser succeeds.
     </p>
    </div>
   </div>
  </div>
  <div id="the-statetag" class="section s3">
   <h2 class="title h3">
    <span><span class="section-number">5.4.3</span> The <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.StateTag"><span
    class="ci">StateTag</span></a></code></span>
   </h2>
   <div class="intro i3">
    <div class="para _1">
     <p>
      Parser combinators often need to check whether a parser has changed the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code> state. In a typical FParsec application these
      checks are performed so frequently that an efficient implementation is important for the overall parser performance. Since a straightforward
      comparison of the complete <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code>
      states can be quite expensive, the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span
      class="ci">CharStream</span></a></code> class provides a shortcut for this purpose: the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code>.
     </p>
    </div>
    <div class="para _2">
     <p>
      The <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code> is a
      simple integer counter that is incremented every time a <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span
      class="ci">CharStream</span></a></code> method changes the state. Thus, if the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code> hasn’t changed, you can safely infer
      that the state hasn’t changed either.<sup class="fn-mark"><a id="the-statetag.:FN:1:B:" href="#the-statetag.:FN:1">[1]</a></sup> Except for some
      special cases, the opposite is also true: if the <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.StateTag"><span
      class="ci">StateTag</span></a></code> has changed, the state has changed too.
     </p>
    </div>
    <div class="para _3 lcinp">
     <p>
      In the following special cases checking whether the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code> has changed is not equivalent to
      checking whether the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code> state
      has changed, because the tag may change even though the state doesn’t:
     </p>
     <ul class="l1">
      <li class="_1">
       A parser calls the basic <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.Skip"><span
       class="ci">Skip</span></a></code> or <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.Read"><span
       class="ci">Read</span></a></code> methods with a 0 offset or an empty argument string.
      </li>
      <li class="_2">
       A parser seeks the <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code> to the
       current position or replaces the user state with the current value.
      </li>
      <li class="_3">
       A parser makes several calls to <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span
       class="ci">CharStream</span></a></code> methods and in later calls undoes the changes it made in earlier calls.
      </li>
     </ul>
    </div>
    <div class="para _4">
     <p>
      The first and second cases only have practical relevance for generic or parameterized parsers and can be simply avoided by checking the
      arguments before calling the respective <code class="fsharp"><a href="../reference/charstream.html#CharStream"><span
      class="ci">CharStream</span></a></code> methods. The third case only arises in the context of backtracking and it too can be easily avoided,
      either by using the <code class="fsharp"><a href="../reference/charstream.html#CharStream_1.members.BacktrackTo"><span
      class="ci">BacktrackTo</span></a></code> method for backtracking or by manually restoring the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code> after the backtracking.
     </p>
    </div>
    <div class="para _5">
     <p>
      In practice these special cases are extremely rare, usually without consequences for the parser behaviour and always easily avoidable. Hence,
      FParsec combinators make free use of the <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.StateTag"><span
      class="ci">StateTag</span></a></code> to check whether a parser has changed the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream"><span class="ci">CharStream</span></a></code> state.
     </p>
    </div>
   </div>
  </div>
  <div id="generalizing" class="section s3">
   <h2 class="title h3">
    <span><span class="section-number">5.4.4</span> Generalizing <code class="fsharp"><a href="../reference/primitives.html#members.:62::62:.."><span
    class="co">&gt;&gt;.</span></a></code></span>
   </h2>
   <div class="intro i3">
    <div class="para _1 lcinp">
     <p>
      The parsers <code class="fsharp"><span class="ci">p1</span> <a href="../reference/primitives.html#members...:62::62:"><span
      class="co">.&gt;&gt;</span></a> <span class="ci">p2</span></code> and <code class="fsharp"><span class="ci">p1</span> <a
      href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <span class="ci">p2</span></code> only return the
      results of <code class="fsharp"><span class="ci">p1</span></code> and <code class="fsharp"><span class="ci">p2</span></code> respectively. If
      you want to combine the results from both <code class="fsharp"><span class="ci">p1</span></code> and <code class="fsharp"><span
      class="ci">p2</span></code>, you could use the <code class="fsharp"><a href="../reference/primitives.html#members.pipe2"><span
      class="ci">pipe2</span></a></code> combinator instead:
     </p>
<pre class="code fsharp"><span class="ck">val</span> <a href="../reference/primitives.html#members.pipe2"><span class="ci">pipe2</span></a><span class="cp">:</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'b</span> <span class="cr">-&gt;</span> <span class="ctv">'c</span><span class="cp">)</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'c</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span></pre>
    </div>
    <div class="para _2">
     <p>
      The parser <code class="fsharp"><a href="../reference/primitives.html#members.pipe2"><span class="ci">pipe2</span></a> <span
      class="ci">p1</span> <span class="ci">p2</span> <span class="ci">f</span></code> will apply <code class="fsharp"><span
      class="ci">p1</span></code> and <code class="fsharp"><span class="ci">p2</span></code> in sequence, exactly like <code class="fsharp"><a
      href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a></code>, but instead of returning one of the result
      values of <code class="fsharp"><span class="ci">p1</span></code> and <code class="fsharp"><span class="ci">p2</span></code> it will return the
      result of the function application <code class="fsharp"><span class="ci">f</span> <span class="ci">x1</span> <span class="ci">x2</span></code>,
      where <code class="fsharp"><span class="ci">x1</span></code> and <code class="fsharp"><span class="ci">x2</span></code> are the results returned
      by <code class="fsharp"><span class="ci">p1</span></code> and <code class="fsharp"><span class="ci">p2</span></code>.
     </p>
    </div>
    <div class="para _3 lcinp">
     <p>
      There are also <code class="fsharp"><a href="../reference/primitives.html#members.pipe3"><span class="ci">pipe3</span></a></code>, <code
      class="fsharp"><a href="../reference/primitives.html#members.pipe4"><span class="ci">pipe4</span></a></code> and <code class="fsharp"><a
      href="../reference/primitives.html#members.pipe5"><span class="ci">pipe5</span></a></code> combinators, in case you need more than two
      arguments. Often these combinators are used to pass arguments to object constructors, like in the following example of a parser for a
      comma‐separated list of XYZ coordinates:
     </p>
<pre class="code fsharp"><span class="ck">type</span> <span class="ci">Data</span> <span class="cp">=</span> <span class="ci">Point</span> <span class="ck">of</span> <span class="ci">float</span><span class="cp">*</span><span class="ci">float</span><span class="cp">*</span><span class="ci">float</span>

<span class="ck">let</span> <span class="ci">ws</span> <span class="cp">=</span> <a href="../reference/charparsers.html#members.spaces"><span class="ci">spaces</span></a>
<span class="ck">let</span> <span class="ci">str</span> <span class="ci">s</span> <span class="cp">=</span> <a href="../reference/charparsers.html#members.pstring"><span class="ci">pstring</span></a> <span class="ci">s</span> <a href="../reference/primitives.html#members...:62::62:"><span class="co">.&gt;&gt;</span></a> <span class="ci">ws</span>
<span class="ck">let</span> <span class="ci">number</span> <span class="cp">=</span> <a href="../reference/charparsers.html#members.pfloat"><span class="ci">pfloat</span></a> <a href="../reference/primitives.html#members...:62::62:"><span class="co">.&gt;&gt;</span></a> <span class="ci">ws</span>
<span class="ck">let</span> <span class="ci">point</span> <span class="cp">=</span> <a href="../reference/primitives.html#members.pipe3"><span class="ci">pipe3</span></a> <span class="ci">number</span> <span class="cp">(</span><span class="ci">str</span> <span class="cs"><span class="cld">"</span>,<span class="crd">"</span></span> <a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <span class="ci">number</span><span class="cp">)</span> <span class="cp">(</span><span class="ci">str</span> <span class="cs"><span class="cld">"</span>,<span class="crd">"</span></span> <a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <span class="ci">number</span><span class="cp">)</span>
                  <span class="cp">(</span><span class="ck">fun</span> <span class="ci">x</span> <span class="ci">y</span> <span class="ci">z</span> <span class="cr">-&gt;</span> <span class="ci">Point</span><span class="cp">(</span><span class="ci">x</span><span class="cp">,</span> <span class="ci">y</span><span class="cp">,</span> <span class="ci">z</span><span class="cp">)</span><span class="cp">)</span>
</pre>
<pre class="code fsharp"><span class="cmd"><span class="cmdp">&gt;</span> <a href="../reference/charparsers.html#members.run"><span class="ci">run</span></a> <span class="ci">point</span> <span class="cs"><span class="cld">"</span>1, 2, 3<span class="crd">"</span></span><span class="cp">;;</span></span>
<span class="cout">val it : ParserResult&lt;Data,unit&gt; = Success: Point (1.0,2.0,3.0)
</span></pre>
    </div>
    <div class="para _4">
     <p>
      If you just want to return the parsed values as a tuple, you can use the predefined <code class="fsharp"><a
      href="../reference/primitives.html#members.tuple2"><span class="ci">tuple2</span></a><span class="co">-</span><span class="cn">5</span></code>
      parsers. For example, <code class="fsharp"><a href="../reference/primitives.html#members.tuple2"><span class="ci">tuple2</span></a> <span
      class="ci">p1</span> <span class="ci">p2</span></code> is equivalent to <code class="fsharp"><a
      href="../reference/primitives.html#members.pipe2"><span class="ci">pipe2</span></a> <span class="ci">p1</span> <span class="ci">p2</span> <span
      class="cp">(</span><span class="ck">fun</span> <span class="ci">x1</span> <span class="ci">x2</span> <span class="cr">-&gt;</span> <span
      class="cp">(</span><span class="ci">x1</span><span class="cp">,</span> <span class="ci">x2</span><span class="cp">)</span></code>.
     </p>
    </div>
    <div class="para _5">
     <p>
      <code class="fsharp"><a href="../reference/primitives.html#members.tuple2"><span class="ci">tuple2</span></a></code> is also available under the
      operator name <code class="fsharp"><a href="../reference/primitives.html#members...:62::62:.."><span class="co">.&gt;&gt;.</span></a></code>, so
      that you can write <code class="fsharp"><span class="ci">p1</span> <a href="../reference/primitives.html#members...:62::62:.."><span
      class="co">.&gt;&gt;.</span></a> <span class="ci">p2</span></code> instead of <code class="fsharp"><a
      href="../reference/primitives.html#members.tuple2"><span class="ci">tuple2</span></a> <span class="ci">p1</span> <span
      class="ci">p2</span></code>.
     </p>
    </div>
    <div class="para _6 lcinp">
     <p>There is no <code class="fsharp"><span class="ci">pipe1</span></code> combinator, but there is an operator for the same purpose:</p>
<pre class="code fsharp"><span class="ck">val</span> <span class="cp">(</span><a href="../reference/primitives.html#members.:124::62::62:"><span class="co">|&gt;&gt;</span></a><span class="cp">)</span><span class="cp">:</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'b</span><span class="cp">)</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span> <span class="ctv">'u</span><span class="cp">&gt;</span>
</pre>
    </div>
    <div class="para _7 lcinp">
     <p>This operator is used similarly to the F#’s ubiquitous pipeline operator <code class="fsharp"><span class="co">|&gt;</span></code>:</p>
<pre class="code fsharp"><span class="ck">type</span> <span class="ci">Expression</span> <span class="cp">=</span> <span class="ci">Number</span> <span class="ck">of</span> <span class="ci">int</span>
                <span class="cp">|</span> <span class="ci">Identifier</span> <span class="ck">of</span> <span class="ci">string</span>

<span class="ck">let</span> <span class="ci">number</span> <span class="cp">=</span> <a href="../reference/charparsers.html#members.pint32"><span class="ci">pint32</span></a> <a href="../reference/primitives.html#members.:124::62::62:"><span class="co">|&gt;&gt;</span></a> <span class="ci">Number</span>
</pre>
<pre class="code fsharp"><span class="cmd"><span class="cmdp">&gt;</span> <a href="../reference/charparsers.html#members.run"><span class="ci">run</span></a> <span class="ci">number</span> <span class="cs"><span class="cld">"</span>123<span class="crd">"</span></span><span class="cp">;;</span></span>
<span class="cout">val it : ParserResult&lt;Expression,unit&gt; = Success: Number 123
</span></pre>
    </div>
   </div>
  </div>
  <div id="the-combinator" class="section s3">
   <h2 class="title h3">
    <span><span class="section-number">5.4.5</span> The <code class="fsharp"><a href="../reference/primitives.html#members.:62::62::61:"><span
    class="co">&gt;&gt;=</span></a></code> combinator</span>
   </h2>
   <div class="intro i3">
    <div class="para _1 lcinp">
     <p>
      All the sequencing and piping combinators we have discussed so far could be implemented with the help of the &#x201C;bind&#x201D; combinator:
     </p>
<pre class="code fsharp"><span class="ck">val</span> <span class="cp">(</span><a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a><span class="cp">)</span><span class="cp">:</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">)</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'b</span><span class="cp">&gt;</span></pre>
    </div>
    <div class="para _2">
     <p>
      Instead of two parsers this combinator takes a parser and a <em>function producing a parser</em> as arguments. The combined parser <code
      class="fsharp"><span class="ci">p</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span
      class="ci">f</span></code> first applies the parser <code class="fsharp"><span class="ci">p</span></code> to the input, then it applies the
      function <code class="fsharp"><span class="ci">f</span></code> to the result returned by <code class="fsharp"><span class="ci">p</span></code>
      and finally it applies the parser returned by <code class="fsharp"><span class="ci">f</span></code> to the input. If we knew in advance that
      <code class="fsharp"><span class="ci">p</span></code> returns <code class="fsharp"><span class="ci">x</span></code> then <code
      class="fsharp"><span class="ci">p</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span
      class="ci">f</span></code> would be equivalent to <code class="fsharp"><span class="ci">p</span> <a
      href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a> <span class="cp">(</span><span
      class="ci">f</span> <span class="ci">x</span><span class="cp">)</span></code>.
     </p>
    </div>
    <div class="para _3">
     <p>
      The <code class="fsharp"><a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a></code> combinator is
      quite versatile. For example, the following code implements five of the previously discussed combinators in terms of <code class="fsharp"><a
      href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a></code> and the trivial <code class="fsharp"><a
      href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a></code> primitive:
     </p>
    </div>
    <div class="para _4 lcinp">
<pre class="code fsharp"><span class="ck">let</span> <a href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a> <span class="ci">x</span> <span class="cp">=</span> <span class="ck">fun</span> <span class="ci">stream</span> <span class="cr">-&gt;</span> <a href="../reference/reply.html"><span class="ci">Reply</span></a><span class="cp">(</span><span class="ci">x</span><span class="cp">)</span>

<span class="ck">let</span> <span class="cp">(</span><a href="../reference/primitives.html#members.:124::62::62:"><span class="co">|&gt;&gt;</span></a><span class="cp">)</span> <span class="ci">p</span>  <span class="ci">f</span>    <span class="cp">=</span> <span class="ci">p</span>  <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">x</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a> <span class="cp">(</span><span class="ci">f</span> <span class="ci">x</span><span class="cp">)</span>
<span class="ck">let</span> <span class="cp">(</span><a href="../reference/primitives.html#members...:62::62:"><span class="co">.&gt;&gt;</span></a><span class="cp">)</span> <span class="ci">p1</span> <span class="ci">p2</span>   <span class="cp">=</span> <span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">x</span> <span class="cr">-&gt;</span> <span class="ci">p2</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">_</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a> <span class="ci">x</span>
<span class="ck">let</span> <span class="cp">(</span><a href="../reference/primitives.html#members.:62::62:.."><span class="co">&gt;&gt;.</span></a><span class="cp">)</span> <span class="ci">p1</span> <span class="ci">p2</span>   <span class="cp">=</span> <span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">_</span> <span class="cr">-&gt;</span> <span class="ci">p2</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">y</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a> <span class="ci">y</span>
<span class="ck">let</span> <span class="cp">(</span><a href="../reference/primitives.html#members...:62::62:.."><span class="co">.&gt;&gt;.</span></a><span class="cp">)</span> <span class="ci">p1</span> <span class="ci">p2</span>  <span class="cp">=</span> <span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">x</span> <span class="cr">-&gt;</span> <span class="ci">p2</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">y</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a> <span class="cp">(</span><span class="ci">x</span><span class="cp">,</span> <span class="ci">y</span><span class="cp">)</span>
<span class="ck">let</span> <a href="../reference/primitives.html#members.pipe2"><span class="ci">pipe2</span></a> <span class="ci">p1</span> <span class="ci">p2</span> <span class="ci">f</span> <span class="cp">=</span> <span class="ci">p1</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">x</span> <span class="cr">-&gt;</span> <span class="ci">p2</span> <a href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a> <span class="ck">fun</span> <span class="ci">y</span> <span class="cr">-&gt;</span> <a href="../reference/primitives.html#members.preturn"><span class="ci">preturn</span></a> <span class="cp">(</span><span class="ci">f</span> <span class="ci">x</span> <span class="ci">y</span><span class="cp">)</span>
</pre>
    </div>
    <div class="para _5">
     <p>
      In typical FParsec code <code class="fsharp"><a href="../reference/primitives.html#members.:62::62::61:"><span
      class="co">&gt;&gt;=</span></a></code> is only seldomly used, because in many situations where <code class="fsharp"><a
      href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a></code> could in principle be used one of the
      other specialized operators is more convenient to use and faster. However, on a conceptual level this combinator is important, because its
      generality allows us to define and test many combinators through their equivalence with a parser defined in terms of <code class="fsharp"><a
      href="../reference/primitives.html#members.:62::62::61:"><span class="co">&gt;&gt;=</span></a></code>. This combinator is also significant for
      the role it plays in the monadic parser construction syntax, see <a href="where-is-the-monad.html">section 5.10</a>.
     </p>
    </div>
   </div>
  </div>
  <div class="fn-list">
   <div class="fn-title">Footnotes:</div>
   <table class="fn">
    <tr class="fn _1">
     <th class="fn _1"><a class="footnote-backlink" id="the-statetag.:FN:1" href="#the-statetag.:FN:1:B:">[1]</a></th>
     <td class="fn _2">
      Of course, this doesn’t apply if you manually set back the <code class="fsharp"><a
      href="../reference/charstream.html#CharStream.members.StateTag"><span class="ci">StateTag</span></a></code> to the old value. There is also the
      purely theoretical possibility that the <code class="fsharp"><a href="../reference/charstream.html#CharStream.members.StateTag"><span
      class="ci">StateTag</span></a></code> has overflown and was incremented exactly 2<sup>64</sup> times (or 2<sup>32</sup> if you define the <code
      class="fsharp"><span class="ci">SMALL_STATETAG</span></code> conditional compiler symbol).
     </td>
    </tr>
   </table>
  </div>
 </div>
 </div>
 </div>
 </div>
</body>
</html>