<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Zandoná Mobile®</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/fzandona/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/fzandona/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:21:41 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>The JSON Parser Monad - Parsing JSON the fun way (Part 3)</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/the-json-parser-monad-parsing-json-the-fun-way-part-3</link>
      <pubDate>Wed, 02 Nov 2011 20:02:00 GMT</pubDate>
      <dc:creator><![CDATA[Zandoná]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2011/11/02/the-json-parser-monad-parsing-json-the-fun-way-part-3/</guid>
      <description><![CDATA[It is finally time to tackle the problem that got us into looking at parsing data structures: a JSON...]]></description>
      <content:encoded><![CDATA[<p>It is finally time to tackle the problem that got us into looking at parsing data structures: a JSON blob in a late night. We started with a simple Parser definition, built very simple parsers, worked our away into building more complex ones by binding them together, and finally wrapped them into Parser Monads to leverage a simpler syntax through F#&rsquo;s Computation Expressions.</p>
<p>We ended Part 2 with a set of general purpose parsers that we will use here to, finally, build the JSON parser.</p>
<p>Make sure to read <a title="Parser Monad - Part 1" href="http://blogs.msdn.com/b/fzandona/archive/2011/10/11/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-1.aspx">Part 1</a> and <a title="Parser Monad - Part 2" href="http://blogs.msdn.com/b/fzandona/archive/2011/10/17/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-2.aspx">Part 2</a> for a refresher if you need it.</p>
<h3>First things first</h3>
<p>We all know how JSON looks like, but for this exercise point your browser to <a title="json.org" href="http://json.org">json.org</a>, and check the details of the structures it is built of. Let&rsquo;s focus on the EBNF-like grammar on the right of the page: the values that form the JSON structured are strings, numbers, objects, arrays, booleans and null &ndash; it is pretty simple to represent that in F# using an algebraic type:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">type</span> <span class="i" onmouseover="showTip(event, 'fstips77', 240)" onmouseout="hideTip(event, 'fstips77', 240)">JSValue</span> <span class="o">=</span> 
    | <span class="i" onmouseover="showTip(event, 'fstips78', 241)" onmouseout="hideTip(event, 'fstips78', 241)">JSString</span> <span class="k">of</span> <span class="i" onmouseover="showTip(event, 'fstips79', 242)" onmouseout="hideTip(event, 'fstips79', 242)">string</span>
    | <span class="i" onmouseover="showTip(event, 'fstips80', 243)" onmouseout="hideTip(event, 'fstips80', 243)">JSNumber</span> <span class="k">of</span> <span class="i" onmouseover="showTip(event, 'fstips81', 244)" onmouseout="hideTip(event, 'fstips81', 244)">float</span>
    | <span class="i" onmouseover="showTip(event, 'fstips82', 245)" onmouseout="hideTip(event, 'fstips82', 245)">JSObject</span> <span class="k">of</span> (<span class="i" onmouseover="showTip(event, 'fstips77', 246)" onmouseout="hideTip(event, 'fstips77', 246)">JSValue</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fstips77', 247)" onmouseout="hideTip(event, 'fstips77', 247)">JSValue</span>) <span class="i" onmouseover="showTip(event, 'fstips12', 248)" onmouseout="hideTip(event, 'fstips12', 248)">list</span>
    | <span class="i" onmouseover="showTip(event, 'fstips83', 249)" onmouseout="hideTip(event, 'fstips83', 249)">JSArray</span> <span class="k">of</span> <span class="i" onmouseover="showTip(event, 'fstips77', 250)" onmouseout="hideTip(event, 'fstips77', 250)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips12', 251)" onmouseout="hideTip(event, 'fstips12', 251)">list</span>
    | <span class="i" onmouseover="showTip(event, 'fstips84', 252)" onmouseout="hideTip(event, 'fstips84', 252)">JSBool</span> <span class="k">of</span> <span class="i" onmouseover="showTip(event, 'fstips85', 253)" onmouseout="hideTip(event, 'fstips85', 253)">bool</span>
    | <span class="i" onmouseover="showTip(event, 'fstips86', 254)" onmouseout="hideTip(event, 'fstips86', 254)">JSNull</span>
<a class="fssniplink" href="http://tomasp.net/fswebsnippets" target="_blank">F# Web Snippets</a>
</pre>
</div>
<p>&nbsp;</p>
<p>This will be our JSON abstract syntax tree and our parser will &ldquo;fill up&rdquo; this structure as it parsers the input string.</p>
<p>There is this simple trick I often use when I&rsquo;m prototyping with some code, I don&rsquo;t know yet how to implement some of the functionality of I need, but I want to rely on F#&rsquo;s type system to make sure I&rsquo;m on the right way. The idea is use Unchecked.defaultof to generate a default value for the return of your function while you don&rsquo;t have an implementation for it (I guess this is just like the <em>NotImplementedException</em> VS throws in when generating class member stubs for you, just that we not throwing any exception in this case... we could, but we are not...). I always keep an <em>undefined</em> function handy, like this:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips87', 255)" onmouseout="hideTip(event, 'fstips87', 255)">undefined</span><span class="o">&lt;</span><span class="o">'</span><span class="i">a</span><span class="o">&gt;</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips88', 256)" onmouseout="hideTip(event, 'fstips88', 256)">Unchecked</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips89', 257)" onmouseout="hideTip(event, 'fstips89', 257)">defaultof</span><span class="o">&lt;</span><span class="o">'</span><span class="i">a</span><span class="o">&gt;</span></pre>
</div>
<p>&nbsp;</p>
<p>For example, let&rsquo;s write the functions of our JSON parser based on the grammar from json.org. The parsers for <em>JSString</em>, <em>JSNumber</em>, <em>JSBool</em> and <em>JSNull</em> are straight forward, they are just <em>JSValue Parsers</em>:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips90', 258)" onmouseout="hideTip(event, 'fstips90', 258)">jsString</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 259)" onmouseout="hideTip(event, 'fstips87', 259)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 260)" onmouseout="hideTip(event, 'fstips77', 260)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 261)" onmouseout="hideTip(event, 'fstips10', 261)">Parser</span><span class="o">&gt;</span>
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips91', 262)" onmouseout="hideTip(event, 'fstips91', 262)">jsNumber</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 263)" onmouseout="hideTip(event, 'fstips87', 263)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 264)" onmouseout="hideTip(event, 'fstips77', 264)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 265)" onmouseout="hideTip(event, 'fstips10', 265)">Parser</span><span class="o">&gt;</span>
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips92', 266)" onmouseout="hideTip(event, 'fstips92', 266)">jsBool</span>  <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 267)" onmouseout="hideTip(event, 'fstips87', 267)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 268)" onmouseout="hideTip(event, 'fstips77', 268)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 269)" onmouseout="hideTip(event, 'fstips10', 269)">Parser</span><span class="o">&gt;</span>
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips93', 270)" onmouseout="hideTip(event, 'fstips93', 270)">jsNull</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 271)" onmouseout="hideTip(event, 'fstips87', 271)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 272)" onmouseout="hideTip(event, 'fstips77', 272)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 273)" onmouseout="hideTip(event, 'fstips10', 273)">Parser</span><span class="o">&gt;</span>
</pre>
</div>
<p>&nbsp;</p>
<p>Note that that <em>JSObject</em> and <em>JSArray</em> both depend on <em>JSValue</em>, and <em>JSValue</em> on them, so these guys will need to be recursive:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fstips94', 274)" onmouseout="hideTip(event, 'fstips94', 274)">jsValue</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips90', 275)" onmouseout="hideTip(event, 'fstips90', 275)">jsString</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips91', 276)" onmouseout="hideTip(event, 'fstips91', 276)">jsNumber</span> <span class="o">&lt;|&gt;</span> <span class="i">jsArray</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips92', 277)" onmouseout="hideTip(event, 'fstips92', 277)">jsBool</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips93', 278)" onmouseout="hideTip(event, 'fstips93', 278)">jsNull</span> <span class="o">&lt;|&gt;</span> <span class="i">jsObject</span>
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips95', 279)" onmouseout="hideTip(event, 'fstips95', 279)">jsElements</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 280)" onmouseout="hideTip(event, 'fstips87', 280)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 281)" onmouseout="hideTip(event, 'fstips77', 281)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips12', 282)" onmouseout="hideTip(event, 'fstips12', 282)">list</span> <span class="i" onmouseover="showTip(event, 'fstips10', 283)" onmouseout="hideTip(event, 'fstips10', 283)">Parser</span><span class="o">&gt;</span>
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips96', 284)" onmouseout="hideTip(event, 'fstips96', 284)">jsArray</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 285)" onmouseout="hideTip(event, 'fstips87', 285)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 286)" onmouseout="hideTip(event, 'fstips77', 286)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 287)" onmouseout="hideTip(event, 'fstips10', 287)">Parser</span><span class="o">&gt;</span>

<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips97', 288)" onmouseout="hideTip(event, 'fstips97', 288)">jsMembers</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 289)" onmouseout="hideTip(event, 'fstips87', 289)">undefined</span><span class="o">&lt;</span>(<span class="i" onmouseover="showTip(event, 'fstips77', 290)" onmouseout="hideTip(event, 'fstips77', 290)">JSValue</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fstips77', 291)" onmouseout="hideTip(event, 'fstips77', 291)">JSValue</span>) <span class="i" onmouseover="showTip(event, 'fstips12', 292)" onmouseout="hideTip(event, 'fstips12', 292)">list</span> <span class="i" onmouseover="showTip(event, 'fstips10', 293)" onmouseout="hideTip(event, 'fstips10', 293)">Parser</span><span class="o">&gt;</span>
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips98', 294)" onmouseout="hideTip(event, 'fstips98', 294)">jsPair</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 295)" onmouseout="hideTip(event, 'fstips87', 295)">undefined</span><span class="o">&lt;</span>(<span class="i" onmouseover="showTip(event, 'fstips77', 296)" onmouseout="hideTip(event, 'fstips77', 296)">JSValue</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fstips77', 297)" onmouseout="hideTip(event, 'fstips77', 297)">JSValue</span>) <span class="i" onmouseover="showTip(event, 'fstips10', 298)" onmouseout="hideTip(event, 'fstips10', 298)">Parser</span><span class="o">&gt;</span>

<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips99', 299)" onmouseout="hideTip(event, 'fstips99', 299)">jsObject</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 300)" onmouseout="hideTip(event, 'fstips87', 300)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 301)" onmouseout="hideTip(event, 'fstips77', 301)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 302)" onmouseout="hideTip(event, 'fstips10', 302)">Parser</span><span class="o">&gt;</span>
</pre>
</div>
<p>&nbsp;</p>
<p>Finally we define the overall <em>JSValue</em> parser as a combination of parsers using the &ldquo;or&rdquo; parser combinator (<em>&lt;|&gt;</em>) form last post, meaning a <em>JSValue</em> parser is a <em>jsString</em> parser, or a <em>jsNumber</em> parser, or a <em>jsArray</em> parser, &hellip;, and so on.</p>
<p>I really like how this representation and types mimic the JSON grammar, for example: a JSON object is a value&nbsp;(<em>&lt;JSValue Parser&gt;)</em>, composed of members (<em>&lt;(JSValue * JSValue) list Parser&gt;)</em> of pairs of string : values (<em>&lt;(JSValue * JSValue) Parser&gt;</em>).</p>
<p>You can actually send the code above to F# Interactive and it will &ldquo;run&rdquo; just fine, showing that so far we've got the types correct:</p>
<p><span style="font-family: courier new,courier;">val jsString : JSValue Parser = null</span><br /><span style="font-family: courier new,courier;">val jsNumber : JSValue Parser = null</span><br /><span style="font-family: courier new,courier;">val jsBool : JSValue Parser = null</span><br /><span style="font-family: courier new,courier;">val jsNull : JSValue Parser = null</span><br /><span style="font-family: courier new,courier;">val jsObject : JSValue Parser = null</span><br /><span style="font-family: courier new,courier;">val jsMembers : (JSValue * JSValue) list Parser = null</span><br /><span style="font-family: courier new,courier;">val jsPair : (JSValue * JSValue) Parser = null</span><br /><span style="font-family: courier new,courier;">val jsArray : JSValue Parser = null</span><br /><span style="font-family: courier new,courier;">val jsElements : JSValue list Parser = null</span><br /><span style="font-family: courier new,courier;">val jsValue : JSValue Parser = Parser &lt;fun:op_LessBarGreater@32&gt;</span></p>
<h3>A parser at a time</h3>
<p>Dividing to conquer&hellip; Let&rsquo;s build a parser a time, substituting the default values by real implementations.</p>
<h4>jsNull Parser</h4>
<p><em>jsNull</em> seems pretty simple to implement, whenever we see a null, we need to return <em>JSNull</em>. We can simply use the symb parser for that:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips100', 303)" onmouseout="hideTip(event, 'fstips100', 303)">jsNull</span> <span class="o">=</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips101', 304)" onmouseout="hideTip(event, 'fstips101', 304)">nullLiteral</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips2', 305)" onmouseout="hideTip(event, 'fstips2', 305)">s2cs</span> <span class="s">"</span><span class="s">null</span><span class="s">"</span>
    <span class="i" onmouseover="showTip(event, 'fstips27', 306)" onmouseout="hideTip(event, 'fstips27', 306)">parser</span> { <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips58', 307)" onmouseout="hideTip(event, 'fstips58', 307)">symb</span> <span class="i" onmouseover="showTip(event, 'fstips101', 308)" onmouseout="hideTip(event, 'fstips101', 308)">nullLiteral</span> <span class="k">in</span> <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fstips86', 309)" onmouseout="hideTip(event, 'fstips86', 309)">JSNull</span>}
</pre>
</div>
<p>&nbsp;</p>
<p>Remember, symb takes a char list as input and returns a parser that is able to parse that string. In this case we don&rsquo;t really need the result of parsing &ldquo;null&rdquo;, we only need that it succeeds&hellip; and if it succeeds, we return <em>JSNull</em> . Let&rsquo;s run it on Interactive:</p>
<p><span style="font-family: courier new,courier;">&gt; s2cs "null" |&gt; apply jsNull;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNull, [])]</span></p>
<h4>jsBool Parser</h4>
<p><em>jsBool</em> is very similar to <em>jsNull</em>, however in this case we can return either <em>JSBool(true)</em>&nbsp;or <em>JSBool(false)</em>: a perfect case for our &ldquo;or&rdquo; parser:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips102', 310)" onmouseout="hideTip(event, 'fstips102', 310)">jsBool</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips103', 311)" onmouseout="hideTip(event, 'fstips103', 311)">trueLit</span> <span class="o">=</span> <span class="s">"</span><span class="s">true</span><span class="s">"</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips2', 312)" onmouseout="hideTip(event, 'fstips2', 312)">s2cs</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips104', 313)" onmouseout="hideTip(event, 'fstips104', 313)">falseLit</span> <span class="o">=</span> <span class="s">"</span><span class="s">false</span><span class="s">"</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips2', 314)" onmouseout="hideTip(event, 'fstips2', 314)">s2cs</span>
    <span class="i" onmouseover="showTip(event, 'fstips27', 315)" onmouseout="hideTip(event, 'fstips27', 315)">parser</span> { <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips58', 316)" onmouseout="hideTip(event, 'fstips58', 316)">symb</span> <span class="i" onmouseover="showTip(event, 'fstips103', 317)" onmouseout="hideTip(event, 'fstips103', 317)">trueLit</span> <span class="k">in</span> <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fstips84', 318)" onmouseout="hideTip(event, 'fstips84', 318)">JSBool</span>(<span class="k">true</span>) } 
    <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips27', 319)" onmouseout="hideTip(event, 'fstips27', 319)">parser</span> { <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips58', 320)" onmouseout="hideTip(event, 'fstips58', 320)">symb</span> <span class="i" onmouseover="showTip(event, 'fstips104', 321)" onmouseout="hideTip(event, 'fstips104', 321)">falseLit</span> <span class="k">in</span> <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fstips84', 322)" onmouseout="hideTip(event, 'fstips84', 322)">JSBool</span>(<span class="k">false</span>) }
</pre>
</div>
<p>&nbsp;</p>
<p>Simple, right? <em>jsBool</em> is a parser that sequences two other parsers, one that parses &ldquo;true&rdquo; and the other that parses &ldquo;false&rdquo;; its return will depend on the parser that succeeds:</p>
<p><span style="font-family: courier new,courier;">&gt; s2cs "true" |&gt; apply jsBool;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSBool true, [])]</span><br /><span style="font-family: courier new,courier;">&gt; s2cs "false" |&gt; apply jsBool;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSBool false, [])]</span></p>
<p><span style="font-family: courier new,courier;">&gt; s2cs "false true false true" |&gt; apply (many jsBool);;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue list * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [([JSBool false; JSBool true; JSBool false; JSBool true], [])]</span></p>
<h4>jsNumber Parser</h4>
<p><em>jsNumber</em> is a bit more complex, check out the number grammar on json.org&hellip; We could use the same approach as before to slowly build it:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips105', 323)" onmouseout="hideTip(event, 'fstips105', 323)">jsNumber</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips106', 324)" onmouseout="hideTip(event, 'fstips106', 324)">digitsParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 325)" onmouseout="hideTip(event, 'fstips87', 325)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips11', 326)" onmouseout="hideTip(event, 'fstips11', 326)">char</span> <span class="i" onmouseover="showTip(event, 'fstips12', 327)" onmouseout="hideTip(event, 'fstips12', 327)">list</span> <span class="i" onmouseover="showTip(event, 'fstips10', 328)" onmouseout="hideTip(event, 'fstips10', 328)">Parser</span><span class="o">&gt;</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips107', 329)" onmouseout="hideTip(event, 'fstips107', 329)">intParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 330)" onmouseout="hideTip(event, 'fstips87', 330)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips11', 331)" onmouseout="hideTip(event, 'fstips11', 331)">char</span> <span class="i" onmouseover="showTip(event, 'fstips12', 332)" onmouseout="hideTip(event, 'fstips12', 332)">list</span> <span class="i" onmouseover="showTip(event, 'fstips10', 333)" onmouseout="hideTip(event, 'fstips10', 333)">Parser</span><span class="o">&gt;</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips108', 334)" onmouseout="hideTip(event, 'fstips108', 334)">fracParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 335)" onmouseout="hideTip(event, 'fstips87', 335)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips11', 336)" onmouseout="hideTip(event, 'fstips11', 336)">char</span> <span class="i" onmouseover="showTip(event, 'fstips12', 337)" onmouseout="hideTip(event, 'fstips12', 337)">list</span> <span class="i" onmouseover="showTip(event, 'fstips10', 338)" onmouseout="hideTip(event, 'fstips10', 338)">Parser</span><span class="o">&gt;</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips109', 339)" onmouseout="hideTip(event, 'fstips109', 339)">expParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips87', 340)" onmouseout="hideTip(event, 'fstips87', 340)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips11', 341)" onmouseout="hideTip(event, 'fstips11', 341)">char</span> <span class="i" onmouseover="showTip(event, 'fstips12', 342)" onmouseout="hideTip(event, 'fstips12', 342)">list</span> <span class="i" onmouseover="showTip(event, 'fstips10', 343)" onmouseout="hideTip(event, 'fstips10', 343)">Parser</span><span class="o">&gt;</span>
    <span class="i" onmouseover="showTip(event, 'fstips87', 344)" onmouseout="hideTip(event, 'fstips87', 344)">undefined</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips77', 345)" onmouseout="hideTip(event, 'fstips77', 345)">JSValue</span> <span class="i" onmouseover="showTip(event, 'fstips10', 346)" onmouseout="hideTip(event, 'fstips10', 346)">Parser</span><span class="o">&gt;</span>
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>digitsParser</em> has to parse <strong>one</strong> to <strong>many digits</strong>; if you remember last post, we can accomplish it with the <em>sat</em> and <em>many1</em> parsers, like this:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips110', 347)" onmouseout="hideTip(event, 'fstips110', 347)">jsNumber</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips106', 348)" onmouseout="hideTip(event, 'fstips106', 348)">digitsParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips39', 349)" onmouseout="hideTip(event, 'fstips39', 349)">many1</span> (<span class="i" onmouseover="showTip(event, 'fstips30', 350)" onmouseout="hideTip(event, 'fstips30', 350)">sat</span> <span class="i" onmouseover="showTip(event, 'fstips1', 351)" onmouseout="hideTip(event, 'fstips1', 351)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips111', 352)" onmouseout="hideTip(event, 'fstips111', 352)">Char</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips112', 353)" onmouseout="hideTip(event, 'fstips112', 353)">IsDigit</span>)
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips107', 354)" onmouseout="hideTip(event, 'fstips107', 354)">intParser</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fstips71', 355)" onmouseout="hideTip(event, 'fstips71', 355)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 356)" onmouseout="hideTip(event, 'fstips37', 356)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 357)" onmouseout="hideTip(event, 'fstips106', 357)">digitsParser</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips108', 358)" onmouseout="hideTip(event, 'fstips108', 358)">fracParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips37', 359)" onmouseout="hideTip(event, 'fstips37', 359)">text</span> [<span class="s">'.'</span>] <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 360)" onmouseout="hideTip(event, 'fstips106', 360)">digitsParser</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips109', 361)" onmouseout="hideTip(event, 'fstips109', 361)">expParser</span> <span class="o">=</span> 
        (<span class="i" onmouseover="showTip(event, 'fstips37', 362)" onmouseout="hideTip(event, 'fstips37', 362)">text</span> [<span class="s">'e'</span>] <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips37', 363)" onmouseout="hideTip(event, 'fstips37', 363)">text</span> [<span class="s">'E'</span>]) <span class="o">&lt;@&gt;</span> 
        (<span class="i" onmouseover="showTip(event, 'fstips71', 364)" onmouseout="hideTip(event, 'fstips71', 364)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 365)" onmouseout="hideTip(event, 'fstips37', 365)">text</span> [<span class="s">'+'</span>] <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips37', 366)" onmouseout="hideTip(event, 'fstips37', 366)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span>
        <span class="i" onmouseover="showTip(event, 'fstips106', 367)" onmouseout="hideTip(event, 'fstips106', 367)">digitsParser</span>
    <span class="i" onmouseover="showTip(event, 'fstips27', 368)" onmouseout="hideTip(event, 'fstips27', 368)">parser</span> {
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips113', 369)" onmouseout="hideTip(event, 'fstips113', 369)">result</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips107', 370)" onmouseout="hideTip(event, 'fstips107', 370)">intParser</span> <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips71', 371)" onmouseout="hideTip(event, 'fstips71', 371)">zeroOrOne</span> <span class="i" onmouseover="showTip(event, 'fstips108', 372)" onmouseout="hideTip(event, 'fstips108', 372)">fracParser</span> <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips71', 373)" onmouseout="hideTip(event, 'fstips71', 373)">zeroOrOne</span> <span class="i" onmouseover="showTip(event, 'fstips109', 374)" onmouseout="hideTip(event, 'fstips109', 374)">expParser</span> 
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips56', 375)" onmouseout="hideTip(event, 'fstips56', 375)">space</span>
        <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips113', 376)" onmouseout="hideTip(event, 'fstips113', 376)">result</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips5', 377)" onmouseout="hideTip(event, 'fstips5', 377)">cs2s</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips1', 378)" onmouseout="hideTip(event, 'fstips1', 378)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips114', 379)" onmouseout="hideTip(event, 'fstips114', 379)">Double</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips115', 380)" onmouseout="hideTip(event, 'fstips115', 380)">Parse</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips80', 381)" onmouseout="hideTip(event, 'fstips80', 381)">JSNumber</span>)
    }     
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>intParser</em> is quite interesting&hellip; it has to sequence <strong>zero or one</strong> applications of a &lsquo;-&lsquo; parser with the <em>digitsParser</em>. We don&rsquo;t have a &ldquo;one or zero&rdquo; combinator in our bag of parsers from last post, and it seems a good candidate to be added to the list, so let&rsquo;s define it:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips71', 226)" onmouseout="hideTip(event, 'fstips71', 226)">zeroOrOne</span> <span class="i" onmouseover="showTip(event, 'fstips72', 227)" onmouseout="hideTip(event, 'fstips72', 227)">p</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 228)" onmouseout="hideTip(event, 'fstips27', 228)">parser</span> { <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips73', 229)" onmouseout="hideTip(event, 'fstips73', 229)">ret</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips72', 230)" onmouseout="hideTip(event, 'fstips72', 230)">p</span> <span class="k">in</span> <span class="k">return</span> <span class="i">ret</span> } <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips27', 231)" onmouseout="hideTip(event, 'fstips27', 231)">parser</span> { <span class="k">return</span> [] }
</pre>
</div>
<p>&nbsp;</p>
<p>When applied, this parser will try to parse the input string using parser <em>p</em>, and if that fails it returns an empty list <em>Parser</em>. Hover over the definition, this is an <em>&lsquo;a list Parser</em>, so <em>p</em> also has to be an <em>&lsquo;a list Parser </em>too, like the <em>text</em> parser defined in the last post:</p>
<p><span style="font-family: courier new,courier;">&gt; [ '-' ] |&gt; apply (zeroOrOne (text ['-']));;</span><br /><span style="font-family: courier new,courier;">val it : (char list * char list) list = [(['-'], [])]</span></p>
<p>Let&rsquo;s then build <em>intParser</em> using it:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips107', 354)" onmouseout="hideTip(event, 'fstips107', 354)">intParser</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fstips71', 355)" onmouseout="hideTip(event, 'fstips71', 355)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 356)" onmouseout="hideTip(event, 'fstips37', 356)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 357)" onmouseout="hideTip(event, 'fstips106', 357)">digitsParser</span>
</pre>
</div>
<p>&nbsp;</p>
<p>We are basically &ldquo;appending&rdquo; two parsers here: <em>zeroOrOne (text ['-'])</em> and <em>digitsParser</em>, this can also be quite common, so let&rsquo;s build a parser combinator for that:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> (<span class="o">&lt;@&gt;</span>) <span class="i" onmouseover="showTip(event, 'fstips72', 232)" onmouseout="hideTip(event, 'fstips72', 232)">p</span> <span class="i" onmouseover="showTip(event, 'fstips74', 233)" onmouseout="hideTip(event, 'fstips74', 233)">q</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 234)" onmouseout="hideTip(event, 'fstips27', 234)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips75', 235)" onmouseout="hideTip(event, 'fstips75', 235)">rp</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips72', 236)" onmouseout="hideTip(event, 'fstips72', 236)">p</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips76', 237)" onmouseout="hideTip(event, 'fstips76', 237)">rq</span><span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips74', 238)" onmouseout="hideTip(event, 'fstips74', 238)">q</span>
    <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips75', 239)" onmouseout="hideTip(event, 'fstips75', 239)">rp</span> <span class="o">@</span> <span class="i">rq</span>)
}
</pre>
</div>
<p>&nbsp;</p>
<p>Now <em>intParser</em>, <em>fracParser</em> and <em>expParser</em> can all be written using&nbsp;that:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips107', 354)" onmouseout="hideTip(event, 'fstips107', 354)">intParser</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fstips71', 355)" onmouseout="hideTip(event, 'fstips71', 355)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 356)" onmouseout="hideTip(event, 'fstips37', 356)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 357)" onmouseout="hideTip(event, 'fstips106', 357)">digitsParser</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips108', 358)" onmouseout="hideTip(event, 'fstips108', 358)">fracParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips37', 359)" onmouseout="hideTip(event, 'fstips37', 359)">text</span> [<span class="s">'.'</span>] <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 360)" onmouseout="hideTip(event, 'fstips106', 360)">digitsParser</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips109', 361)" onmouseout="hideTip(event, 'fstips109', 361)">expParser</span> <span class="o">=</span> 
        (<span class="i" onmouseover="showTip(event, 'fstips37', 362)" onmouseout="hideTip(event, 'fstips37', 362)">text</span> [<span class="s">'e'</span>] <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips37', 363)" onmouseout="hideTip(event, 'fstips37', 363)">text</span> [<span class="s">'E'</span>]) <span class="o">&lt;@&gt;</span> 
        (<span class="i" onmouseover="showTip(event, 'fstips71', 364)" onmouseout="hideTip(event, 'fstips71', 364)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 365)" onmouseout="hideTip(event, 'fstips37', 365)">text</span> [<span class="s">'+'</span>] <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips37', 366)" onmouseout="hideTip(event, 'fstips37', 366)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span>
        <span class="i" onmouseover="showTip(event, 'fstips106', 367)" onmouseout="hideTip(event, 'fstips106', 367)">digitsParser</span>
</pre>
</div>
<p>&nbsp;</p>
<p>All we need to do now is sequence all these parsers, one by one, concatenate the results and return the equivalent <em>JSNumber</em>:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips110', 347)" onmouseout="hideTip(event, 'fstips110', 347)">jsNumber</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips106', 348)" onmouseout="hideTip(event, 'fstips106', 348)">digitsParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips39', 349)" onmouseout="hideTip(event, 'fstips39', 349)">many1</span> (<span class="i" onmouseover="showTip(event, 'fstips30', 350)" onmouseout="hideTip(event, 'fstips30', 350)">sat</span> <span class="i" onmouseover="showTip(event, 'fstips1', 351)" onmouseout="hideTip(event, 'fstips1', 351)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips111', 352)" onmouseout="hideTip(event, 'fstips111', 352)">Char</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips112', 353)" onmouseout="hideTip(event, 'fstips112', 353)">IsDigit</span>)
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips107', 354)" onmouseout="hideTip(event, 'fstips107', 354)">intParser</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fstips71', 355)" onmouseout="hideTip(event, 'fstips71', 355)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 356)" onmouseout="hideTip(event, 'fstips37', 356)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 357)" onmouseout="hideTip(event, 'fstips106', 357)">digitsParser</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips108', 358)" onmouseout="hideTip(event, 'fstips108', 358)">fracParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips37', 359)" onmouseout="hideTip(event, 'fstips37', 359)">text</span> [<span class="s">'.'</span>] <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips106', 360)" onmouseout="hideTip(event, 'fstips106', 360)">digitsParser</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips109', 361)" onmouseout="hideTip(event, 'fstips109', 361)">expParser</span> <span class="o">=</span> 
        (<span class="i" onmouseover="showTip(event, 'fstips37', 362)" onmouseout="hideTip(event, 'fstips37', 362)">text</span> [<span class="s">'e'</span>] <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips37', 363)" onmouseout="hideTip(event, 'fstips37', 363)">text</span> [<span class="s">'E'</span>]) <span class="o">&lt;@&gt;</span> 
        (<span class="i" onmouseover="showTip(event, 'fstips71', 364)" onmouseout="hideTip(event, 'fstips71', 364)">zeroOrOne</span> (<span class="i" onmouseover="showTip(event, 'fstips37', 365)" onmouseout="hideTip(event, 'fstips37', 365)">text</span> [<span class="s">'+'</span>] <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips37', 366)" onmouseout="hideTip(event, 'fstips37', 366)">text</span> [<span class="s">'-'</span>])) <span class="o">&lt;@&gt;</span>
        <span class="i" onmouseover="showTip(event, 'fstips106', 367)" onmouseout="hideTip(event, 'fstips106', 367)">digitsParser</span>
    <span class="i" onmouseover="showTip(event, 'fstips27', 368)" onmouseout="hideTip(event, 'fstips27', 368)">parser</span> {
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips113', 369)" onmouseout="hideTip(event, 'fstips113', 369)">result</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips107', 370)" onmouseout="hideTip(event, 'fstips107', 370)">intParser</span> <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips71', 371)" onmouseout="hideTip(event, 'fstips71', 371)">zeroOrOne</span> <span class="i" onmouseover="showTip(event, 'fstips108', 372)" onmouseout="hideTip(event, 'fstips108', 372)">fracParser</span> <span class="o">&lt;@&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips71', 373)" onmouseout="hideTip(event, 'fstips71', 373)">zeroOrOne</span> <span class="i" onmouseover="showTip(event, 'fstips109', 374)" onmouseout="hideTip(event, 'fstips109', 374)">expParser</span> 
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips56', 375)" onmouseout="hideTip(event, 'fstips56', 375)">space</span>
        <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips113', 376)" onmouseout="hideTip(event, 'fstips113', 376)">result</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips5', 377)" onmouseout="hideTip(event, 'fstips5', 377)">cs2s</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips1', 378)" onmouseout="hideTip(event, 'fstips1', 378)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips114', 379)" onmouseout="hideTip(event, 'fstips114', 379)">Double</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips115', 380)" onmouseout="hideTip(event, 'fstips115', 380)">Parse</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips80', 381)" onmouseout="hideTip(event, 'fstips80', 381)">JSNumber</span>)
    }
</pre>
</div>
<p>&nbsp;</p>
<p>Two comments here: because we are not using any of the combinators that take care of cleaning up spaces, we need to make sure to sequence a space parser in there. Second, all these parsers are <em>char list</em> parsers, so we can append them together in the end to come up with a string representation of the float number. Here it is in Interactive:</p>
<p><span style="font-family: courier new,courier;">&gt; "-1234.5678e-8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber -1.2345678e-05, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "-1234.5678e8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber -1.2345678e+11, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "-1234.5678e+8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber -1.2345678e+11, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "-1234.5678E+8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber -1.2345678e+11, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "1234.5678E+8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber 1.2345678e+11, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "1234E+8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber 1.234e+11, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "1234E-8" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber 1.234e-05, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "1234.5678" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber 1234.5678, [])]</span><br /><span style="font-family: courier new,courier;">&gt; "1234" |&gt; s2cs |&gt; apply jsNumber;;</span><br /><span style="font-family: courier new,courier;">val it : (JSValue * char list) list = [(JSNumber 1234.0, [])]</span></p>
<p>How cool is that?!</p>
<h4>jsString Parser</h4>
<p><em>jsString</em> is bit complex due to all the different&nbsp; &ldquo;production rules&rdquo;. Let&rsquo;s start by building a couple predicates based on those rules, and a helper function &ndash; this is straight out of JSON&rsquo;s grammar:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips117', 383)" onmouseout="hideTip(event, 'fstips117', 383)">isChar</span> <span class="i" onmouseover="showTip(event, 'fstips29', 384)" onmouseout="hideTip(event, 'fstips29', 384)">c</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fstips29', 385)" onmouseout="hideTip(event, 'fstips29', 385)">c</span> <span class="o">&lt;&gt;</span> <span class="s">'\"'</span>) <span class="o">&amp;&amp;</span> (<span class="i" onmouseover="showTip(event, 'fstips29', 386)" onmouseout="hideTip(event, 'fstips29', 386)">c</span> <span class="o">&lt;&gt;</span> <span class="s">'\\'</span>)
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips118', 387)" onmouseout="hideTip(event, 'fstips118', 387)">isEscChar</span> <span class="o">=</span> 
        <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips52', 388)" onmouseout="hideTip(event, 'fstips52', 388)">cs</span> <span class="o">=</span> <span class="s">"</span><span class="s">\"</span><span class="s">\\</span><span class="s">/</span><span class="s">bfnrt</span><span class="s">"</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips3', 389)" onmouseout="hideTip(event, 'fstips3', 389)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips4', 390)" onmouseout="hideTip(event, 'fstips4', 390)">ofSeq</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips53', 391)" onmouseout="hideTip(event, 'fstips53', 391)">Set</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips54', 392)" onmouseout="hideTip(event, 'fstips54', 392)">ofList</span>
        <span class="i" onmouseover="showTip(event, 'fstips52', 393)" onmouseout="hideTip(event, 'fstips52', 393)">cs</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips55', 394)" onmouseout="hideTip(event, 'fstips55', 394)">Contains</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips119', 395)" onmouseout="hideTip(event, 'fstips119', 395)">replaceEscChar</span> <span class="o">=</span> <span class="k">function</span> <span class="s">'b'</span> <span class="k">-&gt;</span> <span class="s">'\b'</span> | <span class="s">'f'</span> <span class="k">-&gt;</span> <span class="s">'\f'</span> | <span class="s">'n'</span> <span class="k">-&gt;</span> <span class="s">'\n'</span>
                                | <span class="s">'r'</span> <span class="k">-&gt;</span> <span class="s">'\r'</span> | <span class="s">'t'</span> <span class="k">-&gt;</span> <span class="s">'\t'</span> | <span class="i" onmouseover="showTip(event, 'fstips120', 396)" onmouseout="hideTip(event, 'fstips120', 396)">other</span> <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips120', 397)" onmouseout="hideTip(event, 'fstips120', 397)">other</span>
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>replaceEscChar</em> will replace a JSON escape character,&nbsp;identified by <em>isEscChar</em>, by its backslash representation. Let&rsquo;s build the <em>escChar Parser</em> with these guys&rsquo; help:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips121', 398)" onmouseout="hideTip(event, 'fstips121', 398)">escChars</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 399)" onmouseout="hideTip(event, 'fstips27', 399)">parser</span> {
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips32', 400)" onmouseout="hideTip(event, 'fstips32', 400)">tChar</span> <span class="s">'\\'</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips29', 401)" onmouseout="hideTip(event, 'fstips29', 401)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips30', 402)" onmouseout="hideTip(event, 'fstips30', 402)">sat</span> <span class="i" onmouseover="showTip(event, 'fstips118', 403)" onmouseout="hideTip(event, 'fstips118', 403)">isEscChar</span>
        <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips119', 404)" onmouseout="hideTip(event, 'fstips119', 404)">replaceEscChar</span> <span class="i" onmouseover="showTip(event, 'fstips29', 405)" onmouseout="hideTip(event, 'fstips29', 405)">c</span>)
    }
</pre>
</div>
<p>&nbsp;</p>
<p>We will also need a unicode parser, which will need to parse 4 hexadecimals, how about starting by putting together a <em>hexDigit Parser</em>?</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips63', 202)" onmouseout="hideTip(event, 'fstips63', 202)">isHexDigit</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips64', 203)" onmouseout="hideTip(event, 'fstips64', 203)">ds</span> <span class="o">=</span> [<span class="s">'A'</span><span class="o">..</span><span class="s">'F'</span>] <span class="o">@</span> [<span class="s">'a'</span><span class="o">..</span><span class="s">'f'</span>] <span class="o">@</span> [<span class="s">'0'</span><span class="o">..</span><span class="s">'9'</span>] <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips53', 204)" onmouseout="hideTip(event, 'fstips53', 204)">Set</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips54', 205)" onmouseout="hideTip(event, 'fstips54', 205)">ofList</span>
    <span class="i" onmouseover="showTip(event, 'fstips64', 206)" onmouseout="hideTip(event, 'fstips64', 206)">ds</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips55', 207)" onmouseout="hideTip(event, 'fstips55', 207)">Contains</span>
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips65', 208)" onmouseout="hideTip(event, 'fstips65', 208)">hexDigit</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips30', 209)" onmouseout="hideTip(event, 'fstips30', 209)">sat</span> <span class="i" onmouseover="showTip(event, 'fstips63', 210)" onmouseout="hideTip(event, 'fstips63', 210)">isHexDigit</span>
</pre>
</div>
<p>&nbsp;</p>
<p>Nothing new here&hellip; based on that, <em>uniChars</em> becomes:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips122', 406)" onmouseout="hideTip(event, 'fstips122', 406)">uniChars</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 407)" onmouseout="hideTip(event, 'fstips27', 407)">parser</span> {
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips37', 408)" onmouseout="hideTip(event, 'fstips37', 408)">text</span> [ <span class="s">'\\'</span>; <span class="s">'u'</span> ]
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips123', 409)" onmouseout="hideTip(event, 'fstips123', 409)">d1</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 410)" onmouseout="hideTip(event, 'fstips65', 410)">hexDigit</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips124', 411)" onmouseout="hideTip(event, 'fstips124', 411)">d2</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 412)" onmouseout="hideTip(event, 'fstips65', 412)">hexDigit</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips125', 413)" onmouseout="hideTip(event, 'fstips125', 413)">d3</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 414)" onmouseout="hideTip(event, 'fstips65', 414)">hexDigit</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips126', 415)" onmouseout="hideTip(event, 'fstips126', 415)">d4</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 416)" onmouseout="hideTip(event, 'fstips65', 416)">hexDigit</span>
        <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips127', 417)" onmouseout="hideTip(event, 'fstips127', 417)">r</span> <span class="o">=</span> 
            <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips128', 418)" onmouseout="hideTip(event, 'fstips128', 418)">s</span> <span class="o">=</span> <span class="k">new</span> <span class="i" onmouseover="showTip(event, 'fstips7', 419)" onmouseout="hideTip(event, 'fstips7', 419)">String</span> [|<span class="i" onmouseover="showTip(event, 'fstips123', 420)" onmouseout="hideTip(event, 'fstips123', 420)">d1</span>; <span class="i" onmouseover="showTip(event, 'fstips124', 421)" onmouseout="hideTip(event, 'fstips124', 421)">d2</span>; <span class="i" onmouseover="showTip(event, 'fstips125', 422)" onmouseout="hideTip(event, 'fstips125', 422)">d3</span>; <span class="i" onmouseover="showTip(event, 'fstips126', 423)" onmouseout="hideTip(event, 'fstips126', 423)">d4</span>|]
            <span class="i" onmouseover="showTip(event, 'fstips129', 424)" onmouseout="hideTip(event, 'fstips129', 424)">Byte</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips130', 425)" onmouseout="hideTip(event, 'fstips130', 425)">Parse</span>(<span class="i" onmouseover="showTip(event, 'fstips128', 426)" onmouseout="hideTip(event, 'fstips128', 426)">s</span>, <span class="i" onmouseover="showTip(event, 'fstips131', 427)" onmouseout="hideTip(event, 'fstips131', 427)">Globalization</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips132', 428)" onmouseout="hideTip(event, 'fstips132', 428)">NumberStyles</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips133', 429)" onmouseout="hideTip(event, 'fstips133', 429)">HexNumber</span>)
            <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips11', 430)" onmouseout="hideTip(event, 'fstips11', 430)">char</span>
        <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fstips127', 431)" onmouseout="hideTip(event, 'fstips127', 431)">r</span>
    }
</pre>
</div>
<p>&nbsp;</p>
<p>There is one more pattern that will repeat on this and next parsers, for example, a JSON string is any char between &lsquo; &ldquo; &lsquo;, objects are members between &ldquo;{ }&rdquo;, arrays are values between &ldquo;[ ]&rdquo;&hellip; It seems a good idea to build a &ldquo;between chars&rdquo; parser, no? Here it goes:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips66', 211)" onmouseout="hideTip(event, 'fstips66', 211)">charToken</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips32', 212)" onmouseout="hideTip(event, 'fstips32', 212)">tChar</span> <span class="o">&gt;</span><span class="o">&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips57', 213)" onmouseout="hideTip(event, 'fstips57', 213)">token</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips67', 214)" onmouseout="hideTip(event, 'fstips67', 214)">betweenChars</span> <span class="i" onmouseover="showTip(event, 'fstips68', 215)" onmouseout="hideTip(event, 'fstips68', 215)">c1</span> <span class="i" onmouseover="showTip(event, 'fstips69', 216)" onmouseout="hideTip(event, 'fstips69', 216)">c2</span> <span class="i" onmouseover="showTip(event, 'fstips70', 217)" onmouseout="hideTip(event, 'fstips70', 217)">f</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 218)" onmouseout="hideTip(event, 'fstips27', 218)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips66', 219)" onmouseout="hideTip(event, 'fstips66', 219)">charToken</span> <span class="i" onmouseover="showTip(event, 'fstips68', 220)" onmouseout="hideTip(event, 'fstips68', 220)">c1</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips40', 221)" onmouseout="hideTip(event, 'fstips40', 221)">r</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips70', 222)" onmouseout="hideTip(event, 'fstips70', 222)">f</span>()
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips66', 223)" onmouseout="hideTip(event, 'fstips66', 223)">charToken</span> <span class="i" onmouseover="showTip(event, 'fstips69', 224)" onmouseout="hideTip(event, 'fstips69', 224)">c2</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fstips40', 225)" onmouseout="hideTip(event, 'fstips40', 225)">r</span>
}
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>betweenChars</em> takes 2 chars and a function (that returns a parser), it binds then together using the <em>let!</em> syntax, and returns the result of applying the parser returned by the function <em>f</em>. And by the way, it comes with a freebie! <em>The charToken Parser</em>: it cleans up spaces after sequencing the <em>tChar Parser</em>. <em>jsString</em> is then defined as:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips116', 382)" onmouseout="hideTip(event, 'fstips116', 382)">jsString</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips117', 383)" onmouseout="hideTip(event, 'fstips117', 383)">isChar</span> <span class="i" onmouseover="showTip(event, 'fstips29', 384)" onmouseout="hideTip(event, 'fstips29', 384)">c</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fstips29', 385)" onmouseout="hideTip(event, 'fstips29', 385)">c</span> <span class="o">&lt;&gt;</span> <span class="s">'\"'</span>) <span class="o">&amp;&amp;</span> (<span class="i" onmouseover="showTip(event, 'fstips29', 386)" onmouseout="hideTip(event, 'fstips29', 386)">c</span> <span class="o">&lt;&gt;</span> <span class="s">'\\'</span>)
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips118', 387)" onmouseout="hideTip(event, 'fstips118', 387)">isEscChar</span> <span class="o">=</span> 
        <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips52', 388)" onmouseout="hideTip(event, 'fstips52', 388)">cs</span> <span class="o">=</span> <span class="s">"</span><span class="s">\"</span><span class="s">\\</span><span class="s">/</span><span class="s">bfnrt</span><span class="s">"</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips3', 389)" onmouseout="hideTip(event, 'fstips3', 389)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips4', 390)" onmouseout="hideTip(event, 'fstips4', 390)">ofSeq</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips53', 391)" onmouseout="hideTip(event, 'fstips53', 391)">Set</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips54', 392)" onmouseout="hideTip(event, 'fstips54', 392)">ofList</span>
        <span class="i" onmouseover="showTip(event, 'fstips52', 393)" onmouseout="hideTip(event, 'fstips52', 393)">cs</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips55', 394)" onmouseout="hideTip(event, 'fstips55', 394)">Contains</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips119', 395)" onmouseout="hideTip(event, 'fstips119', 395)">replaceEscChar</span> <span class="o">=</span> <span class="k">function</span> <span class="s">'b'</span> <span class="k">-&gt;</span> <span class="s">'\b'</span> | <span class="s">'f'</span> <span class="k">-&gt;</span> <span class="s">'\f'</span> | <span class="s">'n'</span> <span class="k">-&gt;</span> <span class="s">'\n'</span>
                                | <span class="s">'r'</span> <span class="k">-&gt;</span> <span class="s">'\r'</span> | <span class="s">'t'</span> <span class="k">-&gt;</span> <span class="s">'\t'</span> | <span class="i" onmouseover="showTip(event, 'fstips120', 396)" onmouseout="hideTip(event, 'fstips120', 396)">other</span> <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips120', 397)" onmouseout="hideTip(event, 'fstips120', 397)">other</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips121', 398)" onmouseout="hideTip(event, 'fstips121', 398)">escChars</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 399)" onmouseout="hideTip(event, 'fstips27', 399)">parser</span> {
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips32', 400)" onmouseout="hideTip(event, 'fstips32', 400)">tChar</span> <span class="s">'\\'</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips29', 401)" onmouseout="hideTip(event, 'fstips29', 401)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips30', 402)" onmouseout="hideTip(event, 'fstips30', 402)">sat</span> <span class="i" onmouseover="showTip(event, 'fstips118', 403)" onmouseout="hideTip(event, 'fstips118', 403)">isEscChar</span>
        <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips119', 404)" onmouseout="hideTip(event, 'fstips119', 404)">replaceEscChar</span> <span class="i" onmouseover="showTip(event, 'fstips29', 405)" onmouseout="hideTip(event, 'fstips29', 405)">c</span>)
    }
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips122', 406)" onmouseout="hideTip(event, 'fstips122', 406)">uniChars</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 407)" onmouseout="hideTip(event, 'fstips27', 407)">parser</span> {
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips37', 408)" onmouseout="hideTip(event, 'fstips37', 408)">text</span> [ <span class="s">'\\'</span>; <span class="s">'u'</span> ]
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips123', 409)" onmouseout="hideTip(event, 'fstips123', 409)">d1</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 410)" onmouseout="hideTip(event, 'fstips65', 410)">hexDigit</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips124', 411)" onmouseout="hideTip(event, 'fstips124', 411)">d2</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 412)" onmouseout="hideTip(event, 'fstips65', 412)">hexDigit</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips125', 413)" onmouseout="hideTip(event, 'fstips125', 413)">d3</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 414)" onmouseout="hideTip(event, 'fstips65', 414)">hexDigit</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips126', 415)" onmouseout="hideTip(event, 'fstips126', 415)">d4</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips65', 416)" onmouseout="hideTip(event, 'fstips65', 416)">hexDigit</span>
        <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips127', 417)" onmouseout="hideTip(event, 'fstips127', 417)">r</span> <span class="o">=</span> 
            <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips128', 418)" onmouseout="hideTip(event, 'fstips128', 418)">s</span> <span class="o">=</span> <span class="k">new</span> <span class="i" onmouseover="showTip(event, 'fstips7', 419)" onmouseout="hideTip(event, 'fstips7', 419)">String</span> [|<span class="i" onmouseover="showTip(event, 'fstips123', 420)" onmouseout="hideTip(event, 'fstips123', 420)">d1</span>; <span class="i" onmouseover="showTip(event, 'fstips124', 421)" onmouseout="hideTip(event, 'fstips124', 421)">d2</span>; <span class="i" onmouseover="showTip(event, 'fstips125', 422)" onmouseout="hideTip(event, 'fstips125', 422)">d3</span>; <span class="i" onmouseover="showTip(event, 'fstips126', 423)" onmouseout="hideTip(event, 'fstips126', 423)">d4</span>|]
            <span class="i" onmouseover="showTip(event, 'fstips129', 424)" onmouseout="hideTip(event, 'fstips129', 424)">Byte</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips130', 425)" onmouseout="hideTip(event, 'fstips130', 425)">Parse</span>(<span class="i" onmouseover="showTip(event, 'fstips128', 426)" onmouseout="hideTip(event, 'fstips128', 426)">s</span>, <span class="i" onmouseover="showTip(event, 'fstips131', 427)" onmouseout="hideTip(event, 'fstips131', 427)">Globalization</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips132', 428)" onmouseout="hideTip(event, 'fstips132', 428)">NumberStyles</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips133', 429)" onmouseout="hideTip(event, 'fstips133', 429)">HexNumber</span>)
            <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips11', 430)" onmouseout="hideTip(event, 'fstips11', 430)">char</span>
        <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fstips127', 431)" onmouseout="hideTip(event, 'fstips127', 431)">r</span>
    }
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips134', 432)" onmouseout="hideTip(event, 'fstips134', 432)">chars</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips38', 433)" onmouseout="hideTip(event, 'fstips38', 433)">many</span> ((<span class="i" onmouseover="showTip(event, 'fstips30', 434)" onmouseout="hideTip(event, 'fstips30', 434)">sat</span> <span class="i" onmouseover="showTip(event, 'fstips117', 435)" onmouseout="hideTip(event, 'fstips117', 435)">isChar</span>) <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips121', 436)" onmouseout="hideTip(event, 'fstips121', 436)">escChars</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips122', 437)" onmouseout="hideTip(event, 'fstips122', 437)">uniChars</span>)
    <span class="i" onmouseover="showTip(event, 'fstips27', 438)" onmouseout="hideTip(event, 'fstips27', 438)">parser</span> {
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips6', 439)" onmouseout="hideTip(event, 'fstips6', 439)">cs</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips67', 440)" onmouseout="hideTip(event, 'fstips67', 440)">betweenChars</span> <span class="s">'\"'</span> <span class="s">'\"'</span> (<span class="k">fun</span> () <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips134', 441)" onmouseout="hideTip(event, 'fstips134', 441)">chars</span>)
        <span class="k">return</span> (<span class="i">cs</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips5', 442)" onmouseout="hideTip(event, 'fstips5', 442)">cs2s</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips78', 443)" onmouseout="hideTip(event, 'fstips78', 443)">JSString</span>)
    }
</pre>
</div>
<p>&nbsp;</p>
<p>This is probably the biggest parser we have ever built!!! The <em>chars Parser</em> is a combination of a parser that parsers any JSON character (<em>sat isChar</em>), or an <em>escChar</em> or a <em>uniChars</em>. We sequence it using our new <em>betweenChars parser</em> combinator and return a <em>JString</em> of the parsed string. Kind of cool...</p>
<h4>The recursive parsers</h4>
<p>We already know that the jsValue parser is a combination of all the individual value parsers:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fstips135', 444)" onmouseout="hideTip(event, 'fstips135', 444)">jsValue</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips116', 445)" onmouseout="hideTip(event, 'fstips116', 445)">jsString</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips110', 446)" onmouseout="hideTip(event, 'fstips110', 446)">jsNumber</span> <span class="o">&lt;|&gt;</span> <span class="i">jsArray</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips102', 447)" onmouseout="hideTip(event, 'fstips102', 447)">jsBool</span> <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips100', 448)" onmouseout="hideTip(event, 'fstips100', 448)">jsNull</span> <span class="o">&lt;|&gt;</span> <span class="i">jsObject</span>
</pre>
</div>
<p>&nbsp;</p>
<p>Let&rsquo;s build the array parser first. Per the JSON grammar, an array is a list of elements between &ldquo;[ ]&rdquo;, and elements are <em>JSValues</em> separated by &lsquo;,&rsquo;. This definition can be easily translated into:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips136', 449)" onmouseout="hideTip(event, 'fstips136', 449)">jsElements</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips42', 450)" onmouseout="hideTip(event, 'fstips42', 450)">sepby</span> <span class="i">jsValue</span> (<span class="i" onmouseover="showTip(event, 'fstips66', 451)" onmouseout="hideTip(event, 'fstips66', 451)">charToken</span> <span class="s">','</span>)
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips137', 452)" onmouseout="hideTip(event, 'fstips137', 452)">jsArray</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 453)" onmouseout="hideTip(event, 'fstips27', 453)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips138', 454)" onmouseout="hideTip(event, 'fstips138', 454)">values</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips67', 455)" onmouseout="hideTip(event, 'fstips67', 455)">betweenChars</span> <span class="s">'['</span> <span class="s">']'</span> (<span class="k">fun</span> () <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips136', 456)" onmouseout="hideTip(event, 'fstips136', 456)">jsElements</span>)
    <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips83', 457)" onmouseout="hideTip(event, 'fstips83', 457)">JSArray</span> <span class="i">values</span>)
    }
</pre>
</div>
<p>&nbsp;</p>
<p>Here we are using the <em>sepby parser</em> combinator we learned last time to build the parser for the array elements. We then put it between &lsquo;[&lsquo; &lsquo;]&rsquo; with <em>betweenChars</em>. It ends up being quite clean.</p>
<p>How about the objects? Objects are members between &ldquo;{ }&rdquo;, and members are pairs separated by &ldquo;,&rdquo;,&nbsp;which are&nbsp;in the format <em>JString : JSValue</em>. This definition also translates easily into F# with our parser combinators:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips139', 458)" onmouseout="hideTip(event, 'fstips139', 458)">jsMembers</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips42', 459)" onmouseout="hideTip(event, 'fstips42', 459)">sepby</span> <span class="i">jsPair</span> (<span class="i" onmouseover="showTip(event, 'fstips66', 460)" onmouseout="hideTip(event, 'fstips66', 460)">charToken</span> <span class="s">','</span>)
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips140', 461)" onmouseout="hideTip(event, 'fstips140', 461)">jsPair</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 462)" onmouseout="hideTip(event, 'fstips27', 462)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips141', 463)" onmouseout="hideTip(event, 'fstips141', 463)">key</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips116', 464)" onmouseout="hideTip(event, 'fstips116', 464)">jsString</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips66', 465)" onmouseout="hideTip(event, 'fstips66', 465)">charToken</span> <span class="s">':'</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips142', 466)" onmouseout="hideTip(event, 'fstips142', 466)">value</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips135', 467)" onmouseout="hideTip(event, 'fstips135', 467)">jsValue</span>
    <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips141', 468)" onmouseout="hideTip(event, 'fstips141', 468)">key</span>, <span class="i">value</span>)
    }
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fstips143', 469)" onmouseout="hideTip(event, 'fstips143', 469)">jsObject</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips27', 470)" onmouseout="hideTip(event, 'fstips27', 470)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fstips144', 471)" onmouseout="hideTip(event, 'fstips144', 471)">members</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips67', 472)" onmouseout="hideTip(event, 'fstips67', 472)">betweenChars</span> <span class="s">'{'</span> <span class="s">'}'</span> (<span class="k">fun</span> () <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips139', 473)" onmouseout="hideTip(event, 'fstips139', 473)">jsMembers</span>)
    <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fstips82', 474)" onmouseout="hideTip(event, 'fstips82', 474)">JSObject</span> <span class="i">members</span>)
    }
</pre>
</div>
<p>&nbsp;</p>
<p>One last thing, let&rsquo;s define a function to easily parse a json string; let&rsquo;s require that any JSON string to be a <em>JSObject</em>, and use <em>runParser</em> with the <em>jsObject</em> to&nbsp;kick off the parsing sequence: given a string, return the JSON AST (which is a <em>JSValue</em>):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips145', 475)" onmouseout="hideTip(event, 'fstips145', 475)">parseJson</span> <span class="o">:</span> (<span class="i" onmouseover="showTip(event, 'fstips79', 476)" onmouseout="hideTip(event, 'fstips79', 476)">string</span> <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips77', 477)" onmouseout="hideTip(event, 'fstips77', 477)">JSValue</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips60', 478)" onmouseout="hideTip(event, 'fstips60', 478)">runParser</span> <span class="i" onmouseover="showTip(event, 'fstips143', 479)" onmouseout="hideTip(event, 'fstips143', 479)">jsObject</span>
</pre>
</div>
<p>&nbsp;</p>
<h3>The moment of truth</h3>
<p>This is the moment we have been waiting so long for&hellip; does all this craziness really work? Go fetch some JSON data and let&rsquo;s try it out, I&rsquo;m grabbing some from <a href="http://json.org/example">http://json.org/example</a>:</p>
<p><span style="font-family: courier new,courier;">{"widget": {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; "debug": "on",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; "window": {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "title": "Sample Konfabulator Widget",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "name": "main_window",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "width": 500,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "height": 500</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; },</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; "image": { </span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "src": "Images/Sun.png",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "name": "sun1",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "hOffset": 250,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "vOffset": 250,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "alignment": "center"</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; },</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; "text": {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "data": "Click Here",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "size": 36,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "style": "bold",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "name": "text1",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "hOffset": 250,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "vOffset": 100,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "alignment": "center",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family: courier new,courier;">}}</span></p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips146', 480)" onmouseout="hideTip(event, 'fstips146', 480)">widgetJson</span> <span class="o">=</span> <span class="s">"</span><span class="s">{</span><span class="s">\"</span><span class="s">widget</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">{</span>
<span class="s"> </span><span class="s">\"</span><span class="s">debug</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">on</span><span class="s">\"</span><span class="s">,</span>
<span class="s"> </span><span class="s">\"</span><span class="s">window</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">{</span>
<span class="s"> </span><span class="s">\"</span><span class="s">title</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">Sample</span><span class="s"> </span><span class="s">Konfabulator</span><span class="s"> </span><span class="s">Widget</span><span class="s">\"</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">name</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">main_window</span><span class="s">\"</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">width</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">500</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">height</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">500</span>
<span class="s"> </span><span class="s">}</span><span class="s">,</span><span class="s"> </span><span class="s">\"</span><span class="s">image</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">{</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">src</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">Images</span><span class="s">/</span><span class="s">Sun</span><span class="s">.</span><span class="s">png</span><span class="s">\"</span><span class="s">,</span>
<span class="s"> </span><span class="s">\"</span><span class="s">name</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">sun1</span><span class="s">\"</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">hOffset</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">250</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">vOffset</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">250</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">alignment</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">center</span><span class="s">\"</span>
<span class="s"> </span><span class="s">}</span><span class="s">,</span><span class="s"> </span><span class="s">\"</span><span class="s">text</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">{</span>
<span class="s"> </span><span class="s">\"</span><span class="s">data</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">Click</span><span class="s"> </span><span class="s">Here</span><span class="s">\"</span><span class="s">,</span>
<span class="s"> </span><span class="s">\"</span><span class="s">size</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">36</span><span class="s">,</span>
<span class="s"> </span><span class="s">\"</span><span class="s">style</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">bold</span><span class="s">\"</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">name</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">text1</span><span class="s">\"</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">hOffset</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">250</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">vOffset</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">100</span><span class="s">,</span><span class="s"> </span>
<span class="s"> </span><span class="s">\"</span><span class="s">alignment</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">center</span><span class="s">\"</span><span class="s">,</span>
<span class="s"> </span><span class="s">\"</span><span class="s">onMouseUp</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">sun1</span><span class="s">.</span><span class="s">opacity</span><span class="s"> </span><span class="s">=</span><span class="s"> </span><span class="s">(</span><span class="s">sun1</span><span class="s">.</span><span class="s">opacity</span><span class="s"> </span><span class="s">/</span><span class="s"> </span><span class="s">100</span><span class="s">)</span><span class="s"> </span><span class="s">*</span><span class="s"> </span><span class="s">90</span><span class="s">;</span><span class="s">\"</span>
<span class="s"> </span><span class="s">}</span>
<span class="s">}</span><span class="s">}</span><span class="s">"</span>
</pre>
</div>
<p><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p><span style="font-family: courier new,courier;">&gt; parseJson widgetJson;;</span><br /><span style="font-family: courier new,courier;">val it : JSValue =</span><br /><span style="font-family: courier new,courier;">&nbsp; JSObject</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; [(JSString "widget",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSObject</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [(JSString "debug", JSString "on");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "window",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSObject</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [(JSString "title", JSString "Sample Konfabulator Widget");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "name", JSString "main_window");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "width", JSNumber 500.0);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "height", JSNumber 500.0)]);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "image",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSObject</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [(JSString "src", JSString "Images/Sun.png");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "name", JSString "sun1");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "hOffset", JSNumber 250.0);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "vOffset", JSNumber 250.0);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "alignment", JSString "center")]);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "text",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSObject</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [(JSString "data", JSString "Click Here");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "size", JSNumber 36.0);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "style", JSString "bold");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "name", JSString "text1");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "hOffset", JSNumber 250.0);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "vOffset", JSNumber 100.0);</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "alignment", JSString "center");</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (JSString "onMouseUp",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSString "sun1.opacity = (sun1.opacity / 100) * 90;")])])]</span></p>
<p><span style="text-decoration: underline;">Ladies and gentlemen, it works!!!</span> I can see some watery eyes out there, and it is ok, building monadic parsers is most definitely an emotional experience!</p>
<p>Make sure to get all the parsers and play with them at <a href="http://fssnip.net/">http://fssnip.net/</a> <br />&bull;&nbsp;<a title="Parser Monad and combinators" href="http://fssnip.net/8S">Parser Monad and combinators<br /></a>&bull;&nbsp;<a title="JSON Parser Monad" href="http://fssnip.net/8T">JSON Parser</a></p>
<h3>Wrapping up</h3>
<p>This is just like Lego for functional programmers: from parsing a single character to parsing full JSON strings by &ldquo;simply&rdquo; composing pieces of parsers together! Now you understand why I completely forgot why I needed a JSON parser in the first place :-).</p>
<p>That said, and now that we are calming down a little bit, it seems we are still missing an piece &ndash; if you compare the result above with the "boring parsing" from Part 1, you will notice we here have just a JSON AST, while there, we ended up with a &ldquo;real&rdquo; F# type&hellip; I guess we will need to look at that in the next post.</p>
<p>Stay tuned and let me know your comments!</p>
<h3>Parsing JSON the fun way series</h3>
<p>&bull; <a title="Part 1: Building a parser from scratch with Dr. Seuss help (part 1)" href="http://bit.ly/qPBllg">Part 1: Building a parser from scratch with Dr. Seuss help (part 1) <br /></a>&bull; <a title="Part 2: Tricking you into Parser Monads (it's not going to hurt, I promise)" href="http://bit.ly/rl3swK">Part 2: Tricking you into Parser Monads (it's not going to hurt, I promise)<br /></a>&bull; <a title="Part 3: The JSON Parser Monad" href="http://bit.ly/rSIjjP">Part 3: The JSON Parser Monad</a></p>
<p>&nbsp;</p>
<!-- HTML code for ToolTips -->
<div id="fstips1" class="tip">namespace System</div>
<div id="fstips2" class="tip">val s2cs : (seq&lt;'a&gt; -&gt; 'a list)<br /><br />Full name: JSONParser.s2cs</div>
<div id="fstips3" class="tip">Multiple items <br />module List<br /><br />from Microsoft.FSharp.Collections <br /><br />--------------------<br /> <br />type List&lt;'T&gt; =<br />&nbsp;&nbsp;| ( [] )<br />&nbsp;&nbsp;| ( :: ) of 'T * 'T list<br />&nbsp;&nbsp;with<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.IEnumerable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Head : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsEmpty : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Item : index:int -&gt; 'T with get<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Tail : 'T list<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Cons : head:'T * tail:'T list -&gt; 'T list<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Empty : 'T list<br />&nbsp;&nbsp;end<br /><br />Full name: Microsoft.FSharp.Collections.List&lt;_&gt;<br /><br />&nbsp;&nbsp;type: List&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'T&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips4" class="tip">val ofSeq : seq&lt;'T&gt; -&gt; 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.ofSeq</div>
<div id="fstips5" class="tip">val cs2s : char list -&gt; String<br /><br />Full name: JSONParser.cs2s</div>
<div id="fstips6" class="tip">val cs : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips7" class="tip">type String =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte * int * int * System.Text.Encoding -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char [] * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Chars : int -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Contains : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : int * char [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string * bool * System.Globalization.CultureInfo -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEnumerator : unit -&gt; System.CharEnumerator<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Insert : int * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsNormalized : unit -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsNormalized : System.Text.NormalizationForm -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Normalize : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Normalize : System.Text.NormalizationForm -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadLeft : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadLeft : int * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadRight : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadRight : int * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Replace : char * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Replace : string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * int -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : string [] * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * int * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : string [] * int * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string * bool * System.Globalization.CultureInfo -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Substring : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Substring : int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToCharArray : unit -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToCharArray : int * int -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLower : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLower : System.Globalization.CultureInfo -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLowerInvariant : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpper : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpper : System.Globalization.CultureInfo -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpperInvariant : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Trim : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Trim : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member TrimEnd : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member TrimStart : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val Empty : string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * bool -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * System.Globalization.CultureInfo * System.Globalization.CompareOptions -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * bool * System.Globalization.CultureInfo -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * bool -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * bool * System.Globalization.CultureInfo -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * System.Globalization.CultureInfo * System.Globalization.CompareOptions -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CompareOrdinal : string * string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CompareOrdinal : string * int * string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat&lt;'T&gt; : System.Collections.Generic.IEnumerable&lt;'T&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : System.Collections.Generic.IEnumerable&lt;string&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string * string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Equals : string * string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Equals : string * string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : System.IFormatProvider * string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Intern : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsInterned : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNullOrEmpty : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNullOrWhiteSpace : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * string [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join&lt;'T&gt; : string * System.Collections.Generic.IEnumerable&lt;'T&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * System.Collections.Generic.IEnumerable&lt;string&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * string [] * int * int -&gt; string<br />&nbsp;&nbsp;end<br /><br />Full name: System.String<br /><br />&nbsp;&nbsp;type: String<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fstips8" class="tip">type Array =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : System.Array * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : System.Array * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEnumerator : unit -&gt; System.Collections.IEnumerator<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLength : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLongLength : int -&gt; int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLowerBound : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetUpperBound : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int [] -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 [] -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int * int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 * int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int * int * int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 * int64 * int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member Initialize : unit -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsFixedSize : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsReadOnly : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSynchronized : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LongLength : int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member Rank : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SyncRoot : obj<br />&nbsp;&nbsp;&nbsp;&nbsp;static member AsReadOnly&lt;'T&gt; : 'T [] -&gt; System.Collections.ObjectModel.ReadOnlyCollection&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * obj * System.Collections.IComparer -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * 'T * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * int * int * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * int * int * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * int * int * obj * System.Collections.IComparer -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * int * int * 'T * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Clear : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConstrainedCopy : System.Array * int * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertAll&lt;'TInput,'TOutput&gt; : 'TInput [] * System.Converter&lt;'TInput,'TOutput&gt; -&gt; 'TOutput []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * System.Array * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * System.Array * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * int * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * int64 * System.Array * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int64 [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int [] * int [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int * int * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Exists&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Find&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindAll&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * int * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLast&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * int * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ForEach&lt;'T&gt; : 'T [] * System.Action&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Resize&lt;'T&gt; : 'T [] * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Reverse : System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Reverse : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * System.Comparison&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * System.Collections.Generic.IComparer&lt;'TKey&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * int * int * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * int * int * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * int * int * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * int * int * System.Collections.Generic.IComparer&lt;'TKey&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TrueForAll&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Array<br /><br />&nbsp;&nbsp;type: Array<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: Collections.IList<br />&nbsp;&nbsp;implements: Collections.ICollection<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable</div>
<div id="fstips9" class="tip">val ofList : 'T list -&gt; 'T []<br /><br />Full name: Microsoft.FSharp.Collections.Array.ofList</div>
<div id="fstips10" class="tip">Multiple items <br />union case Parser.Parser: (char list -&gt; ('a * char list) list) -&gt; 'a Parser <br /><br />--------------------<br /> <br />type 'a Parser = | Parser of (char list -&gt; ('a * char list) list)<br /><br />Full name: JSONParser.Parser&lt;_&gt;</div>
<div id="fstips11" class="tip">Multiple items <br />val char : 'T -&gt; char (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.char <br /><br />--------------------<br /> <br />type char = Char<br /><br />Full name: Microsoft.FSharp.Core.char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips12" class="tip">type 'T list = List&lt;'T&gt;<br /><br />Full name: Microsoft.FSharp.Collections.list&lt;_&gt;<br /><br />&nbsp;&nbsp;type: 'T list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'T&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips13" class="tip">val parse : 'a Parser -&gt; (char list -&gt; ('a * char list) list)<br /><br />Full name: JSONParser.parse</div>
<div id="fstips14" class="tip">val p : (char list -&gt; ('a * char list) list)</div>
<div id="fstips15" class="tip">type ParserBuilder =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;new : unit -&gt; ParserBuilder<br />&nbsp;&nbsp;&nbsp;&nbsp;member Bind : p:'c Parser * f:('c -&gt; 'd Parser) -&gt; 'd Parser<br />&nbsp;&nbsp;&nbsp;&nbsp;member Return : a:'e -&gt; 'e Parser<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReturnFrom : a:'a -&gt; 'a<br />&nbsp;&nbsp;&nbsp;&nbsp;member Zero : unit -&gt; 'b Parser<br />&nbsp;&nbsp;end<br /><br />Full name: JSONParser.ParserBuilder</div>
<div id="fstips16" class="tip">val x : ParserBuilder</div>
<div id="fstips17" class="tip">member ParserBuilder.Return : a:'e -&gt; 'e Parser<br /><br />Full name: JSONParser.ParserBuilder.Return</div>
<div id="fstips18" class="tip">val a : 'e</div>
<div id="fstips19" class="tip">member ParserBuilder.Bind : p:'c Parser * f:('c -&gt; 'd Parser) -&gt; 'd Parser<br /><br />Full name: JSONParser.ParserBuilder.Bind</div>
<div id="fstips20" class="tip">val p : 'c Parser</div>
<div id="fstips21" class="tip">val f : ('c -&gt; 'd Parser)</div>
<div id="fstips22" class="tip">val c' : 'c</div>
<div id="fstips23" class="tip">val cs' : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips24" class="tip">member ParserBuilder.Zero : unit -&gt; 'b Parser<br /><br />Full name: JSONParser.ParserBuilder.Zero</div>
<div id="fstips25" class="tip">member ParserBuilder.ReturnFrom : a:'a -&gt; 'a<br /><br />Full name: JSONParser.ParserBuilder.ReturnFrom</div>
<div id="fstips26" class="tip">val a : 'a</div>
<div id="fstips27" class="tip">val parser : ParserBuilder<br /><br />Full name: JSONParser.parser</div>
<div id="fstips28" class="tip">val item : char Parser<br /><br />Full name: JSONParser.item</div>
<div id="fstips29" class="tip">val c : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips30" class="tip">val sat : (char -&gt; bool) -&gt; char Parser<br /><br />Full name: JSONParser.sat</div>
<div id="fstips31" class="tip">val pred : (char -&gt; bool)</div>
<div id="fstips32" class="tip">val tChar : char -&gt; char Parser<br /><br />Full name: JSONParser.tChar</div>
<div id="fstips33" class="tip">val p : 'a Parser</div>
<div id="fstips34" class="tip">val q : 'a Parser</div>
<div id="fstips35" class="tip">val x : 'a * char list</div>
<div id="fstips36" class="tip">val xs : ('a * char list) list<br /><br />&nbsp;&nbsp;type: ('a * char list) list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a * char list&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a * char list&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips37" class="tip">val text : char list -&gt; char list Parser<br /><br />Full name: JSONParser.text <br /><br /><em>Given a char list, returns a parser that parsers it</em></div>
<div id="fstips38" class="tip">val many : 'a Parser -&gt; 'a list Parser<br /><br />Full name: JSONParser.many <br /><br /><em>Combines many (0 or more) applications of parser p</em></div>
<div id="fstips39" class="tip">val many1 : 'a Parser -&gt; 'a list Parser<br /><br />Full name: JSONParser.many1 <br /><br /><em>Combines at least one (1 or more) applications of parser p</em></div>
<div id="fstips40" class="tip">val r : 'a</div>
<div id="fstips41" class="tip">val rs : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips42" class="tip">val sepby : 'a Parser -&gt; 'b Parser -&gt; 'a list Parser<br /><br />Full name: JSONParser.sepby <br /><br /><em>Combines 0 or more applications of parser p separated by parser sep</em></div>
<div id="fstips43" class="tip">val sep : 'b Parser</div>
<div id="fstips44" class="tip">val sepby1 : 'a Parser -&gt; 'b Parser -&gt; 'a list Parser<br /><br />Full name: JSONParser.sepby1 <br /><br /><em>Combines 1 or more applications of parser p separated by parser sep</em></div>
<div id="fstips45" class="tip">val chainl : 'a Parser -&gt; ('a -&gt; 'a -&gt; 'a) Parser -&gt; 'a -&gt; 'a Parser<br /><br />Full name: JSONParser.chainl <br /><br /><em>Chain 0 or more applications of parser p separated by applications of parser op</em></div>
<div id="fstips46" class="tip">val op : ('a -&gt; 'a -&gt; 'a) Parser</div>
<div id="fstips47" class="tip">val chainl1 : 'a Parser -&gt; ('a -&gt; 'a -&gt; 'a) Parser -&gt; 'a Parser<br /><br />Full name: JSONParser.chainl1 <br /><br /><em>Chain 1 or more applications of parser p separated by applications of parser op</em></div>
<div id="fstips48" class="tip">val rest : ('a -&gt; 'a Parser)</div>
<div id="fstips49" class="tip">val f : ('a -&gt; 'a -&gt; 'a)</div>
<div id="fstips50" class="tip">val r' : 'a</div>
<div id="fstips51" class="tip">val isSpace : (char -&gt; bool)<br /><br />Full name: JSONParser.isSpace</div>
<div id="fstips52" class="tip">val cs : Set&lt;char&gt;<br /><br />&nbsp;&nbsp;type: Set&lt;char&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.Generic.ICollection&lt;char&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips53" class="tip">Multiple items <br />module Set<br /><br />from Microsoft.FSharp.Collections <br /><br />--------------------<br /> <br />type Set&lt;'T (requires comparison)&gt; =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;interface IComparable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.IEnumerable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.ICollection&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;new : elements:seq&lt;'T&gt; -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Add : value:'T -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Contains : value:'T -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;override Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsProperSubsetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsProperSupersetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSubsetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSupersetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : value:'T -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Count : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsEmpty : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member MaximumElement : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;member MinimumElement : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ( + ) : set1:Set&lt;'T&gt; * set2:Set&lt;'T&gt; -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ( - ) : set1:Set&lt;'T&gt; * set2:Set&lt;'T&gt; -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;end<br /><br />Full name: Microsoft.FSharp.Collections.Set&lt;_&gt;<br /><br />&nbsp;&nbsp;type: Set&lt;'T&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.Generic.ICollection&lt;'T&gt;<br />&nbsp;&nbsp;implements: seq&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips54" class="tip">val ofList : 'T list -&gt; Set&lt;'T&gt; (requires comparison)<br /><br />Full name: Microsoft.FSharp.Collections.Set.ofList</div>
<div id="fstips55" class="tip">member Set.Contains : value:'T -&gt; bool</div>
<div id="fstips56" class="tip">val space : char list Parser<br /><br />Full name: JSONParser.space</div>
<div id="fstips57" class="tip">val token : 'a Parser -&gt; 'a Parser<br /><br />Full name: JSONParser.token</div>
<div id="fstips58" class="tip">val symb : (char list -&gt; char list Parser)<br /><br />Full name: JSONParser.symb</div>
<div id="fstips59" class="tip">val apply : 'a Parser -&gt; (char list -&gt; ('a * char list) list)<br /><br />Full name: JSONParser.apply</div>
<div id="fstips60" class="tip">val runParser : 'a Parser -&gt; (seq&lt;char&gt; -&gt; 'a)<br /><br />Full name: JSONParser.runParser</div>
<div id="fstips61" class="tip">val failwith : string -&gt; 'T<br /><br />Full name: Microsoft.FSharp.Core.Operators.failwith</div>
<div id="fstips62" class="tip">val result : 'a</div>
<div id="fstips63" class="tip">val isHexDigit : (char -&gt; bool)<br /><br />Full name: JSONParser.isHexDigit</div>
<div id="fstips64" class="tip">val ds : Set&lt;char&gt;<br /><br />&nbsp;&nbsp;type: Set&lt;char&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.Generic.ICollection&lt;char&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips65" class="tip">val hexDigit : char Parser<br /><br />Full name: JSONParser.hexDigit</div>
<div id="fstips66" class="tip">val charToken : (char -&gt; char Parser)<br /><br />Full name: JSONParser.charToken</div>
<div id="fstips67" class="tip">val betweenChars : char -&gt; char -&gt; (unit -&gt; 'a Parser) -&gt; 'a Parser<br /><br />Full name: JSONParser.betweenChars</div>
<div id="fstips68" class="tip">val c1 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips69" class="tip">val c2 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips70" class="tip">val f : (unit -&gt; 'a Parser)</div>
<div id="fstips71" class="tip">val zeroOrOne : 'a list Parser -&gt; 'a list Parser<br /><br />Full name: JSONParser.zeroOrOne</div>
<div id="fstips72" class="tip">val p : 'a list Parser</div>
<div id="fstips73" class="tip">val ret : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips74" class="tip">val q : 'a list Parser</div>
<div id="fstips75" class="tip">val rp : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips76" class="tip">val rq : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips77" class="tip">type JSValue =<br />&nbsp;&nbsp;| JSString of string<br />&nbsp;&nbsp;| JSNumber of float<br />&nbsp;&nbsp;| JSObject of (JSValue * JSValue) list<br />&nbsp;&nbsp;| JSArray of JSValue list<br />&nbsp;&nbsp;| JSBool of bool<br />&nbsp;&nbsp;| JSNull<br /><br />Full name: JSONParser.JSValue<br /><br />&nbsp;&nbsp;type: JSValue<br />&nbsp;&nbsp;implements: IEquatable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fstips78" class="tip">union case JSValue.JSString: string -&gt; JSValue</div>
<div id="fstips79" class="tip">Multiple items <br />val string : 'T -&gt; string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string <br /><br />--------------------<br /> <br />type string = String<br /><br />Full name: Microsoft.FSharp.Core.string<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fstips80" class="tip">union case JSValue.JSNumber: float -&gt; JSValue</div>
<div id="fstips81" class="tip">Multiple items <br />val float : 'T -&gt; float (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.float <br /><br />--------------------<br /> <br />type float&lt;'Measure&gt; = float<br /><br />Full name: Microsoft.FSharp.Core.float&lt;_&gt;<br /><br />&nbsp;&nbsp;type: float&lt;'Measure&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IComparable&lt;float&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;float&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;inherits: ValueType<br /> <br /><br />--------------------<br /> <br />type float = Double<br /><br />Full name: Microsoft.FSharp.Core.float<br /><br />&nbsp;&nbsp;type: float<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;float&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;float&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips82" class="tip">union case JSValue.JSObject: (JSValue * JSValue) list -&gt; JSValue</div>
<div id="fstips83" class="tip">union case JSValue.JSArray: JSValue list -&gt; JSValue</div>
<div id="fstips84" class="tip">union case JSValue.JSBool: bool -&gt; JSValue</div>
<div id="fstips85" class="tip">type bool = Boolean<br /><br />Full name: Microsoft.FSharp.Core.bool<br /><br />&nbsp;&nbsp;type: bool<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;bool&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;bool&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips86" class="tip">union case JSValue.JSNull: JSValue</div>
<div id="fstips87" class="tip">val undefined&lt;'a&gt; : 'a<br /><br />Full name: JSONParser.undefined</div>
<div id="fstips88" class="tip">module Unchecked<br /><br />from Microsoft.FSharp.Core.Operators</div>
<div id="fstips89" class="tip">val defaultof&lt;'T&gt; : 'T<br /><br />Full name: Microsoft.FSharp.Core.Operators.Unchecked.defaultof</div>
<div id="fstips90" class="tip">val jsString' : JSValue Parser<br /><br />Full name: JSONParser.jsString'</div>
<div id="fstips91" class="tip">val jsNumber' : JSValue Parser<br /><br />Full name: JSONParser.jsNumber'</div>
<div id="fstips92" class="tip">val jsBool' : JSValue Parser<br /><br />Full name: JSONParser.jsBool'</div>
<div id="fstips93" class="tip">val jsNull' : JSValue Parser<br /><br />Full name: JSONParser.jsNull'</div>
<div id="fstips94" class="tip">val jsValue' : JSValue Parser<br /><br />Full name: JSONParser.jsValue'</div>
<div id="fstips95" class="tip">val jsElements' : JSValue list Parser<br /><br />Full name: JSONParser.jsElements'</div>
<div id="fstips96" class="tip">val jsArray' : JSValue Parser<br /><br />Full name: JSONParser.jsArray'</div>
<div id="fstips97" class="tip">val jsMembers' : (JSValue * JSValue) list Parser<br /><br />Full name: JSONParser.jsMembers'</div>
<div id="fstips98" class="tip">val jsPair' : (JSValue * JSValue) Parser<br /><br />Full name: JSONParser.jsPair'</div>
<div id="fstips99" class="tip">val jsObject' : JSValue Parser<br /><br />Full name: JSONParser.jsObject'</div>
<div id="fstips100" class="tip">val jsNull : JSValue Parser<br /><br />Full name: JSONParser.jsNull</div>
<div id="fstips101" class="tip">val nullLiteral : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips102" class="tip">val jsBool : JSValue Parser<br /><br />Full name: JSONParser.jsBool</div>
<div id="fstips103" class="tip">val trueLit : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips104" class="tip">val falseLit : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips105" class="tip">val jsNumber'' : JSValue Parser<br /><br />Full name: JSONParser.jsNumber''</div>
<div id="fstips106" class="tip">val digitsParser : char list Parser</div>
<div id="fstips107" class="tip">val intParser : char list Parser</div>
<div id="fstips108" class="tip">val fracParser : char list Parser</div>
<div id="fstips109" class="tip">val expParser : char list Parser</div>
<div id="fstips110" class="tip">val jsNumber : JSValue Parser<br /><br />Full name: JSONParser.jsNumber</div>
<div id="fstips111" class="tip">type Char =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : char<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertFromUtf32 : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertToUtf32 : char * char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertToUtf32 : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetNumericValue : char -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetNumericValue : string * int -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetUnicodeCategory : char -&gt; System.Globalization.UnicodeCategory<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetUnicodeCategory : string * int -&gt; System.Globalization.UnicodeCategory<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsControl : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsControl : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsDigit : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsDigit : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsHighSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsHighSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetter : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetter : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetterOrDigit : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetterOrDigit : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLowSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLowSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLower : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLower : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNumber : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNumber : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPunctuation : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPunctuation : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSeparator : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSeparator : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogatePair : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogatePair : char * char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSymbol : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSymbol : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsUpper : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsUpper : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsWhiteSpace : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsWhiteSpace : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLower : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLower : char * System.Globalization.CultureInfo -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLowerInvariant : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToString : char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpper : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpper : char * System.Globalization.CultureInfo -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpperInvariant : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * char -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Char<br /><br />&nbsp;&nbsp;type: Char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips112" class="tip">Multiple overloads <br />Char.IsDigit(c: char) : bool <br />Char.IsDigit(s: string, index: int) : bool</div>
<div id="fstips113" class="tip">val result : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips114" class="tip">type Double =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : float -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : float -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string * System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : float<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : float<br />&nbsp;&nbsp;&nbsp;&nbsp;static val Epsilon : float<br />&nbsp;&nbsp;&nbsp;&nbsp;static val NegativeInfinity : float<br />&nbsp;&nbsp;&nbsp;&nbsp;static val PositiveInfinity : float<br />&nbsp;&nbsp;&nbsp;&nbsp;static val NaN : float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsInfinity : float -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNaN : float -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNegativeInfinity : float -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPositiveInfinity : float -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.IFormatProvider -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * float -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * System.Globalization.NumberStyles * System.IFormatProvider * float -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Double<br /><br />&nbsp;&nbsp;type: Double<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;float&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;float&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips115" class="tip">Multiple overloads <br />Double.Parse(s: string) : float <br />Double.Parse(s: string, provider: IFormatProvider) : float <br />Double.Parse(s: string, style: Globalization.NumberStyles) : float <br />Double.Parse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider) : float</div>
<div id="fstips116" class="tip">val jsString : JSValue Parser<br /><br />Full name: JSONParser.jsString</div>
<div id="fstips117" class="tip">val isChar : (char -&gt; bool)</div>
<div id="fstips118" class="tip">val isEscChar : (char -&gt; bool)</div>
<div id="fstips119" class="tip">val replaceEscChar : (char -&gt; char)</div>
<div id="fstips120" class="tip">val other : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips121" class="tip">val escChars : char Parser</div>
<div id="fstips122" class="tip">val uniChars : char Parser</div>
<div id="fstips123" class="tip">val d1 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips124" class="tip">val d2 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips125" class="tip">val d3 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips126" class="tip">val d4 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips127" class="tip">val r : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips128" class="tip">val s : String<br /><br />&nbsp;&nbsp;type: String<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fstips129" class="tip">type Byte =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : System.Byte -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : System.Byte -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string * System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : System.Byte<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : System.Byte<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; System.Byte<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles -&gt; System.Byte<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.IFormatProvider -&gt; System.Byte<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -&gt; System.Byte<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * System.Byte -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * System.Globalization.NumberStyles * System.IFormatProvider * System.Byte -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Byte<br /><br />&nbsp;&nbsp;type: Byte<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;byte&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;byte&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips130" class="tip">Multiple overloads <br />Byte.Parse(s: string) : byte <br />Byte.Parse(s: string, provider: IFormatProvider) : byte <br />Byte.Parse(s: string, style: Globalization.NumberStyles) : byte <br />Byte.Parse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider) : byte</div>
<div id="fstips131" class="tip">namespace System.Globalization</div>
<div id="fstips132" class="tip">type NumberStyles =<br />&nbsp;&nbsp;| None = 0<br />&nbsp;&nbsp;| AllowLeadingWhite = 1<br />&nbsp;&nbsp;| AllowTrailingWhite = 2<br />&nbsp;&nbsp;| AllowLeadingSign = 4<br />&nbsp;&nbsp;| AllowTrailingSign = 8<br />&nbsp;&nbsp;| AllowParentheses = 16<br />&nbsp;&nbsp;| AllowDecimalPoint = 32<br />&nbsp;&nbsp;| AllowThousands = 64<br />&nbsp;&nbsp;| AllowExponent = 128<br />&nbsp;&nbsp;| AllowCurrencySymbol = 256<br />&nbsp;&nbsp;| AllowHexSpecifier = 512<br />&nbsp;&nbsp;| Integer = 7<br />&nbsp;&nbsp;| HexNumber = 515<br />&nbsp;&nbsp;| Number = 111<br />&nbsp;&nbsp;| Float = 167<br />&nbsp;&nbsp;| Currency = 383<br />&nbsp;&nbsp;| Any = 511<br /><br />Full name: System.Globalization.NumberStyles<br /><br />&nbsp;&nbsp;type: Globalization.NumberStyles<br />&nbsp;&nbsp;inherits: Enum<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips133" class="tip">field Globalization.NumberStyles.HexNumber = 515</div>
<div id="fstips134" class="tip">val chars : char list Parser</div>
<div id="fstips135" class="tip">val jsValue : JSValue Parser<br /><br />Full name: JSONParser.jsValue</div>
<div id="fstips136" class="tip">val jsElements : JSValue list Parser<br /><br />Full name: JSONParser.jsElements</div>
<div id="fstips137" class="tip">val jsArray : JSValue Parser<br /><br />Full name: JSONParser.jsArray</div>
<div id="fstips138" class="tip">val values : JSValue list<br /><br />&nbsp;&nbsp;type: JSValue list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;JSValue&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips139" class="tip">val jsMembers : (JSValue * JSValue) list Parser<br /><br />Full name: JSONParser.jsMembers</div>
<div id="fstips140" class="tip">val jsPair : (JSValue * JSValue) Parser<br /><br />Full name: JSONParser.jsPair</div>
<div id="fstips141" class="tip">val key : JSValue<br /><br />&nbsp;&nbsp;type: JSValue<br />&nbsp;&nbsp;implements: IEquatable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fstips142" class="tip">val value : JSValue<br /><br />&nbsp;&nbsp;type: JSValue<br />&nbsp;&nbsp;implements: IEquatable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;JSValue&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fstips143" class="tip">val jsObject : JSValue Parser<br /><br />Full name: JSONParser.jsObject</div>
<div id="fstips144" class="tip">val members : (JSValue * JSValue) list<br /><br />&nbsp;&nbsp;type: (JSValue * JSValue) list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;JSValue * JSValue&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;JSValue * JSValue&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fstips145" class="tip">val parseJson : (string -&gt; JSValue)<br /><br />Full name: JSONParser.parseJson</div>
<div id="fstips146" class="tip">val widgetJson : string<br /><br />Full name: JSONParser.widgetJson<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>]]></content:encoded>
    </item>
    <item>
      <title>Parsing JSON the fun way: monadic parsers, records and type providers (Part 2)</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-2</link>
      <pubDate>Mon, 17 Oct 2011 15:44:00 GMT</pubDate>
      <dc:creator><![CDATA[Zandoná]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2011/10/17/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-2/</guid>
      <description><![CDATA[We went through the process of building a parser from scratch in part 1, starting by a parser that...]]></description>
      <content:encoded><![CDATA[<p>We went through the process of building a parser from scratch in <a title="Parsing JSON the fun way - Part 1" href="http://blogs.msdn.com/b/fzandona/archive/2011/10/11/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-1.aspx">part 1</a>, starting by a parser that can read a single char from an input string, and then&nbsp; sequencing it to build more capable parsers. I ended it up by saying we have the building blocks to build general parsers and that F# can provide us with some magic if we wrap up our parsers into computation expressions.</p>
<p>We will stick to the one line programming language once more for part 2 (last time, promise), and will slowly get to the magical Parser Monads. By the end of this post, we should have all parsers from the <a title="Monadic Parsing in Haskell" href="http://www.cs.nott.ac.uk/~gmh/pearl.pdf">Monadic Parsing in Haskell</a> paper up and running.</p>
<h3>Sugar Love</h3>
<p>You probably noticed we kept using expressions like &ldquo;a thing Parser&rdquo;, &ldquo;an &lsquo;a Parser&rdquo;, &ldquo;satisfy this predicate Parser&rdquo;, etc. everywhere in <a title="Fun Parsers Part 1" href="http://blogs.msdn.com/b/fzandona/archive/2011/10/20/10223458.aspx">part 1 of the series</a>. It seems logical, at this point, to embrace this concept and code it accordingly in F#, doesn&rsquo;t it? Remembering again Dr. Seuss&rsquo; parser definition using F# notation:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&lsquo;a Parser : char list -&gt; (&lsquo;a * char list) list</span></p>
<p>Let&rsquo;s create a &ldquo;container&rdquo; for our parsers using an <a title="Algebraic Type" href="http://en.wikipedia.org/wiki/Algebraic_type">algebraic type</a> &ndash; we will simply take the parser definition as-is, and enclose it into a Parser container:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">type</span> <span class="o">'</span><span class="i">a</span> <span class="i" onmouseover="showTip(event, 'fun0210', 11)" onmouseout="hideTip(event, 'fun0210', 11)">Parser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 12)" onmouseout="hideTip(event, 'fun0210', 12)">Parser</span> <span class="k">of</span> (<span class="i" onmouseover="showTip(event, 'fun0211', 13)" onmouseout="hideTip(event, 'fun0211', 13)">char</span> <span class="i" onmouseover="showTip(event, 'fun0212', 14)" onmouseout="hideTip(event, 'fun0212', 14)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">a</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun0211', 15)" onmouseout="hideTip(event, 'fun0211', 15)">char</span> <span class="i" onmouseover="showTip(event, 'fun0212', 16)" onmouseout="hideTip(event, 'fun0212', 16)">list</span>) <span class="i" onmouseover="showTip(event, 'fun0212', 17)" onmouseout="hideTip(event, 'fun0212', 17)">list</span>)
<a class="fssniplink" href="http://tomasp.net/fswebsnippets" target="_blank">F# Web Snippets</a>
</pre>
</div>
<p>&nbsp;</p>
<p>Got it? We didn&rsquo;t really do much, literally just copied and pasted Dr. Seuss definition&hellip; Any of the parsers we built in part 1 can be encapsulated into this <em>Parser</em> container, for example, remember our char Parser called <em>cParser</em>?</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0213', 18)" onmouseout="hideTip(event, 'fun0213', 18)">cParser</span> <span class="o">=</span> <span class="k">function</span> [] <span class="k">-&gt;</span> [] | <span class="i" onmouseover="showTip(event, 'fun0214', 19)" onmouseout="hideTip(event, 'fun0214', 19)">c</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun0215', 20)" onmouseout="hideTip(event, 'fun0215', 20)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun0214', 21)" onmouseout="hideTip(event, 'fun0214', 21)">c</span>, <span class="i" onmouseover="showTip(event, 'fun0215', 22)" onmouseout="hideTip(event, 'fun0215', 22)">cs</span>]
</pre>
</div>
<p>&nbsp;</p>
<p>Let&rsquo;s wrap it into the Parser type and call it item (adopting the name convention from Erik's paper):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0216', 23)" onmouseout="hideTip(event, 'fun0216', 23)">item</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 24)" onmouseout="hideTip(event, 'fun0210', 24)">Parser</span> (<span class="k">function</span> [] <span class="k">-&gt;</span> [] | <span class="i" onmouseover="showTip(event, 'fun0217', 25)" onmouseout="hideTip(event, 'fun0217', 25)">c</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun026', 26)" onmouseout="hideTip(event, 'fun026', 26)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun0217', 27)" onmouseout="hideTip(event, 'fun0217', 27)">c</span>, <span class="i" onmouseover="showTip(event, 'fun026', 28)" onmouseout="hideTip(event, 'fun026', 28)">cs</span>])
</pre>
</div>
<p>&nbsp;</p>
<p>Hover your mouse over <em>item</em> and let me know what you see&hellip; Correct! As expected <em>item</em> is now officially a <em><span style="text-decoration: underline;">char Parser</span></em>! Let&rsquo;s test it and see if it works (<em>s2cs</em> was defined in the last post):</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; item;;</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&nbsp; "Test" |&gt; s2cs |&gt; item;;</span><br /><span style="font-family: courier new,courier;">&nbsp; ------------------^^^^</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">C:\Users\fzandona\AppData\Local\Temp\stdin(3,19): error FS0001: This expression was expected to have type</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; char list -&gt; 'a&nbsp;&nbsp;&nbsp; </span><br /><span style="font-family: courier new,courier;">but here has type</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; char Parser&nbsp;</span></p>
<p>Oops! Clearly we cannot use the same approach we've been using here; we need to first extract the function form inside the <em>Parser</em> type before applying it. Thanks to F#&rsquo;s pattern matching, we can write:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0218', 29)" onmouseout="hideTip(event, 'fun0218', 29)">parse</span> (<span class="i" onmouseover="showTip(event, 'fun0210', 30)" onmouseout="hideTip(event, 'fun0210', 30)">Parser</span> <span class="i" onmouseover="showTip(event, 'fun0219', 31)" onmouseout="hideTip(event, 'fun0219', 31)">p</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0219', 32)" onmouseout="hideTip(event, 'fun0219', 32)">p</span> 
</pre>
</div>
<p>&nbsp;</p>
<p>And use it like this:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse item;;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 's'; 't'])]</span></p>
<p>Good, we are back in business!</p>
<p>Digressing a little bit here,&nbsp;you&rsquo;ve probably already noticed that I really like to chain functions together by &ldquo;pipelining&rdquo; them using the pipeline operator ( |&gt; ); it looks very expressive to me, for example, the F# line above can be read as: take &ldquo;Text&rdquo; and send it to s2cs, take the result (a char list) and send it to (parse item). Compare it to, where you need to read the code backwards:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; parse item (s2cs "Text");;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 'x'; 't'])]</span></p>
<p>Back on track, we will continue wrapping all parsers we&rsquo;ve built so far with our <em>Parser</em> container in a minute, but let&rsquo;s focus initially at these 3 functions we worked on:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0220', 33)" onmouseout="hideTip(event, 'fun0220', 33)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun0221', 34)" onmouseout="hideTip(event, 'fun0221', 34)">thing</span> <span class="o">=</span> <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun0222', 35)" onmouseout="hideTip(event, 'fun0222', 35)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun0221', 36)" onmouseout="hideTip(event, 'fun0221', 36)">thing</span>, <span class="i" onmouseover="showTip(event, 'fun0222', 37)" onmouseout="hideTip(event, 'fun0222', 37)">cs</span>]
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0223', 38)" onmouseout="hideTip(event, 'fun0223', 38)">zeroParser</span> () <span class="o">=</span> <span class="k">fun</span> _ <span class="k">-&gt;</span> []
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0224', 39)" onmouseout="hideTip(event, 'fun0224', 39)">bindParser</span> (<span class="i" onmouseover="showTip(event, 'fun0219', 40)" onmouseout="hideTip(event, 'fun0219', 40)">p</span><span class="o">:</span>(<span class="i" onmouseover="showTip(event, 'fun0211', 41)" onmouseout="hideTip(event, 'fun0211', 41)">char</span> <span class="i" onmouseover="showTip(event, 'fun0212', 42)" onmouseout="hideTip(event, 'fun0212', 42)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">a</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun0211', 43)" onmouseout="hideTip(event, 'fun0211', 43)">char</span> <span class="i" onmouseover="showTip(event, 'fun0212', 44)" onmouseout="hideTip(event, 'fun0212', 44)">list</span>) <span class="i" onmouseover="showTip(event, 'fun0212', 45)" onmouseout="hideTip(event, 'fun0212', 45)">list</span>), (<span class="i" onmouseover="showTip(event, 'fun0225', 46)" onmouseout="hideTip(event, 'fun0225', 46)">f</span> <span class="o">:</span> <span class="o">'</span><span class="i">a</span> <span class="k">-&gt;</span> (<span class="i" onmouseover="showTip(event, 'fun0211', 47)" onmouseout="hideTip(event, 'fun0211', 47)">char</span> <span class="i" onmouseover="showTip(event, 'fun0212', 48)" onmouseout="hideTip(event, 'fun0212', 48)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">b</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun0211', 49)" onmouseout="hideTip(event, 'fun0211', 49)">char</span> <span class="i" onmouseover="showTip(event, 'fun0212', 50)" onmouseout="hideTip(event, 'fun0212', 50)">list</span>) <span class="i" onmouseover="showTip(event, 'fun0212', 51)" onmouseout="hideTip(event, 'fun0212', 51)">list</span>))) <span class="o">=</span> 
    <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 52)" onmouseout="hideTip(event, 'fun026', 52)">cs</span> <span class="k">-&gt;</span> 
        <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun0219', 53)" onmouseout="hideTip(event, 'fun0219', 53)">p</span> <span class="i" onmouseover="showTip(event, 'fun026', 54)" onmouseout="hideTip(event, 'fun026', 54)">cs</span> <span class="k">with</span>
        | (<span class="i" onmouseover="showTip(event, 'fun0226', 55)" onmouseout="hideTip(event, 'fun0226', 55)">c'</span>, <span class="i" onmouseover="showTip(event, 'fun0227', 56)" onmouseout="hideTip(event, 'fun0227', 56)">cs'</span>)<span class="o">::</span>_ <span class="k">-&gt;</span> (<span class="i" onmouseover="showTip(event, 'fun0225', 57)" onmouseout="hideTip(event, 'fun0225', 57)">f</span> <span class="i" onmouseover="showTip(event, 'fun0226', 58)" onmouseout="hideTip(event, 'fun0226', 58)">c'</span>) <span class="i" onmouseover="showTip(event, 'fun0227', 59)" onmouseout="hideTip(event, 'fun0227', 59)">cs'</span>
        | [] <span class="k">-&gt;</span> []
</pre>
</div>
<p>&nbsp;</p>
<p>We use these guys a lot so let&rsquo;s give them some TLC. Not sure if you realized, but they all comply with Dr. Seuss definition, so it&nbsp;is&nbsp;going to be&nbsp;a good thing to encapsulate them into the new <em>Parser</em> type, giving us:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0228', 60)" onmouseout="hideTip(event, 'fun0228', 60)">returnParser'</span> <span class="i" onmouseover="showTip(event, 'fun0221', 61)" onmouseout="hideTip(event, 'fun0221', 61)">thing</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 62)" onmouseout="hideTip(event, 'fun0210', 62)">Parser</span> (<span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 63)" onmouseout="hideTip(event, 'fun026', 63)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun0221', 64)" onmouseout="hideTip(event, 'fun0221', 64)">thing</span>, <span class="i" onmouseover="showTip(event, 'fun026', 65)" onmouseout="hideTip(event, 'fun026', 65)">cs</span>])
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0229', 66)" onmouseout="hideTip(event, 'fun0229', 66)">zeroParser'</span> () <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 67)" onmouseout="hideTip(event, 'fun0210', 67)">Parser</span> (<span class="k">fun</span> _ <span class="k">-&gt;</span> [])
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0230', 68)" onmouseout="hideTip(event, 'fun0230', 68)">bindParser'</span> (<span class="i" onmouseover="showTip(event, 'fun0231', 69)" onmouseout="hideTip(event, 'fun0231', 69)">p</span> <span class="o">:</span> (<span class="o">'</span><span class="i">a</span> <span class="i" onmouseover="showTip(event, 'fun0210', 70)" onmouseout="hideTip(event, 'fun0210', 70)">Parser</span>), <span class="i" onmouseover="showTip(event, 'fun0232', 71)" onmouseout="hideTip(event, 'fun0232', 71)">f</span> <span class="o">:</span> (<span class="o">'</span><span class="i">a</span> <span class="k">-&gt;</span> <span class="o">'</span><span class="i">b</span> <span class="i" onmouseover="showTip(event, 'fun0210', 72)" onmouseout="hideTip(event, 'fun0210', 72)">Parser</span>)) <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun0210', 73)" onmouseout="hideTip(event, 'fun0210', 73)">Parser</span>(
        <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 74)" onmouseout="hideTip(event, 'fun026', 74)">cs</span> <span class="k">-&gt;</span> 
            <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun0218', 75)" onmouseout="hideTip(event, 'fun0218', 75)">parse</span> <span class="i" onmouseover="showTip(event, 'fun0231', 76)" onmouseout="hideTip(event, 'fun0231', 76)">p</span> <span class="i" onmouseover="showTip(event, 'fun026', 77)" onmouseout="hideTip(event, 'fun026', 77)">cs</span> <span class="k">with</span> 
            | (<span class="i" onmouseover="showTip(event, 'fun0226', 78)" onmouseout="hideTip(event, 'fun0226', 78)">c'</span>, <span class="i" onmouseover="showTip(event, 'fun0227', 79)" onmouseout="hideTip(event, 'fun0227', 79)">cs'</span>)<span class="o">::</span>_ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0218', 80)" onmouseout="hideTip(event, 'fun0218', 80)">parse</span> (<span class="i" onmouseover="showTip(event, 'fun0232', 81)" onmouseout="hideTip(event, 'fun0232', 81)">f</span> <span class="i" onmouseover="showTip(event, 'fun0226', 82)" onmouseout="hideTip(event, 'fun0226', 82)">c'</span>) <span class="i" onmouseover="showTip(event, 'fun0227', 83)" onmouseout="hideTip(event, 'fun0227', 83)">cs'</span>
            | [] <span class="k">-&gt;</span> []
    )
</pre>
</div>
<p>&nbsp;</p>
<p>Note that the only difference from this snippet and the previous one is the existence of the parser container, and the use of our <em>parse</em> function to extract the parser from the container before applying it. By the way, hover your mouse over these functions and note how cleaner the type definitions are, we got rid of all that &ldquo;<em>char list</em>&rdquo; noise thanks to the <em>Parser</em> type!</p>
<p>Second, because these function/parsers are so important, and now that we have them beautifully wrapped, how about putting them into a type class for &ldquo;organizational reasons&rdquo;?</p>
<div class="snippet">
<pre class="fssnip"><span class="k">type</span> <span class="i" onmouseover="showTip(event, 'fun0233', 84)" onmouseout="hideTip(event, 'fun0233', 84)">ParserBuilder</span> () <span class="o">=</span>
    <span class="k">member</span> <span class="i" onmouseover="showTip(event, 'fun0234', 85)" onmouseout="hideTip(event, 'fun0234', 85)">x</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0235', 86)" onmouseout="hideTip(event, 'fun0235', 86)">Return</span> <span class="i" onmouseover="showTip(event, 'fun0236', 87)" onmouseout="hideTip(event, 'fun0236', 87)">a</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 88)" onmouseout="hideTip(event, 'fun0210', 88)">Parser</span> (<span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 89)" onmouseout="hideTip(event, 'fun026', 89)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun0236', 90)" onmouseout="hideTip(event, 'fun0236', 90)">a</span>, <span class="i" onmouseover="showTip(event, 'fun026', 91)" onmouseout="hideTip(event, 'fun026', 91)">cs</span>])
    <span class="k">member</span> <span class="i" onmouseover="showTip(event, 'fun0234', 92)" onmouseout="hideTip(event, 'fun0234', 92)">x</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0237', 93)" onmouseout="hideTip(event, 'fun0237', 93)">Bind</span> (<span class="i" onmouseover="showTip(event, 'fun0238', 94)" onmouseout="hideTip(event, 'fun0238', 94)">p</span>, <span class="i" onmouseover="showTip(event, 'fun0239', 95)" onmouseout="hideTip(event, 'fun0239', 95)">f</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 96)" onmouseout="hideTip(event, 'fun0210', 96)">Parser</span> (<span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 97)" onmouseout="hideTip(event, 'fun026', 97)">cs</span> <span class="k">-&gt;</span> 
        <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun0218', 98)" onmouseout="hideTip(event, 'fun0218', 98)">parse</span> <span class="i" onmouseover="showTip(event, 'fun0238', 99)" onmouseout="hideTip(event, 'fun0238', 99)">p</span> <span class="i" onmouseover="showTip(event, 'fun026', 100)" onmouseout="hideTip(event, 'fun026', 100)">cs</span> <span class="k">with</span>
        | (<span class="i" onmouseover="showTip(event, 'fun0240', 101)" onmouseout="hideTip(event, 'fun0240', 101)">c'</span>, <span class="i" onmouseover="showTip(event, 'fun0227', 102)" onmouseout="hideTip(event, 'fun0227', 102)">cs'</span>)<span class="o">::</span>_ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0218', 103)" onmouseout="hideTip(event, 'fun0218', 103)">parse</span> (<span class="i" onmouseover="showTip(event, 'fun0239', 104)" onmouseout="hideTip(event, 'fun0239', 104)">f</span> <span class="i" onmouseover="showTip(event, 'fun0240', 105)" onmouseout="hideTip(event, 'fun0240', 105)">c'</span>) <span class="i" onmouseover="showTip(event, 'fun0227', 106)" onmouseout="hideTip(event, 'fun0227', 106)">cs'</span>
        | [] <span class="k">-&gt;</span> []
    )
    <span class="k">member</span> <span class="i" onmouseover="showTip(event, 'fun0234', 107)" onmouseout="hideTip(event, 'fun0234', 107)">x</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0241', 108)" onmouseout="hideTip(event, 'fun0241', 108)">Zero</span> () <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 109)" onmouseout="hideTip(event, 'fun0210', 109)">Parser</span> (<span class="k">fun</span> _ <span class="k">-&gt;</span> [])
    <span class="k">member</span> <span class="i" onmouseover="showTip(event, 'fun0234', 110)" onmouseout="hideTip(event, 'fun0234', 110)">x</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0242', 111)" onmouseout="hideTip(event, 'fun0242', 111)">ReturnFrom</span> <span class="i" onmouseover="showTip(event, 'fun0243', 112)" onmouseout="hideTip(event, 'fun0243', 112)">a</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0243', 113)" onmouseout="hideTip(event, 'fun0243', 113)">a</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0244', 114)" onmouseout="hideTip(event, 'fun0244', 114)">parser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0233', 115)" onmouseout="hideTip(event, 'fun0233', 115)">ParserBuilder</span>()
</pre>
</div>
<p>&nbsp;</p>
<p>No changes here, just a class with our previous functions as members, simple and clean (well, I actually sneaked in another member called <em>ReturnFrom</em>, which is just&nbsp;an id function, meaning it returns whatever it receives as input; you will see why we need it later). We also defined a <em>parser</em> value, which is just an instance of our <em>ParserBuilder</em> class.</p>
<p>The next two parsers we built last time were <em>satisfyParser</em> and the <em>tcParser</em> (&ldquo;this specific char Parser&rdquo;):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0245', 116)" onmouseout="hideTip(event, 'fun0245', 116)">satisfyParser</span> <span class="i" onmouseover="showTip(event, 'fun0246', 117)" onmouseout="hideTip(event, 'fun0246', 117)">pred</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun0224', 118)" onmouseout="hideTip(event, 'fun0224', 118)">bindParser</span>(<span class="i" onmouseover="showTip(event, 'fun0213', 119)" onmouseout="hideTip(event, 'fun0213', 119)">cParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun0217', 120)" onmouseout="hideTip(event, 'fun0217', 120)">c</span> <span class="k">-&gt;</span>
        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun0246', 121)" onmouseout="hideTip(event, 'fun0246', 121)">pred</span> <span class="i" onmouseover="showTip(event, 'fun0217', 122)" onmouseout="hideTip(event, 'fun0217', 122)">c</span> <span class="k">then</span> <span class="i" onmouseover="showTip(event, 'fun0220', 123)" onmouseout="hideTip(event, 'fun0220', 123)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun0217', 124)" onmouseout="hideTip(event, 'fun0217', 124)">c</span> <span class="k">else</span> <span class="i" onmouseover="showTip(event, 'fun0223', 125)" onmouseout="hideTip(event, 'fun0223', 125)">zeroParser</span>()
    )

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0247', 126)" onmouseout="hideTip(event, 'fun0247', 126)">tcParser</span> <span class="i" onmouseover="showTip(event, 'fun0217', 127)" onmouseout="hideTip(event, 'fun0217', 127)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0245', 128)" onmouseout="hideTip(event, 'fun0245', 128)">satisfyParser</span> ((<span class="o">=</span>) <span class="i" onmouseover="showTip(event, 'fun0217', 129)" onmouseout="hideTip(event, 'fun0217', 129)">c</span>)
</pre>
</div>
<p>&nbsp;</p>
<p>We should build them in the new neater way by using the <em>parser</em> instance (<em>let parser = ParserBuilder()</em>) and the <em>item</em> parser:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0248', 130)" onmouseout="hideTip(event, 'fun0248', 130)">satisfyParser'</span> <span class="i" onmouseover="showTip(event, 'fun0246', 131)" onmouseout="hideTip(event, 'fun0246', 131)">pred</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun0244', 132)" onmouseout="hideTip(event, 'fun0244', 132)">parser</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0249', 133)" onmouseout="hideTip(event, 'fun0249', 133)">Bind</span>(<span class="i" onmouseover="showTip(event, 'fun0216', 134)" onmouseout="hideTip(event, 'fun0216', 134)">item</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun0217', 135)" onmouseout="hideTip(event, 'fun0217', 135)">c</span> <span class="k">-&gt;</span>
        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun0246', 136)" onmouseout="hideTip(event, 'fun0246', 136)">pred</span> <span class="i" onmouseover="showTip(event, 'fun0217', 137)" onmouseout="hideTip(event, 'fun0217', 137)">c</span> <span class="k">then</span> <span class="i" onmouseover="showTip(event, 'fun0244', 138)" onmouseout="hideTip(event, 'fun0244', 138)">parser</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0250', 139)" onmouseout="hideTip(event, 'fun0250', 139)">Return</span> <span class="i" onmouseover="showTip(event, 'fun0217', 140)" onmouseout="hideTip(event, 'fun0217', 140)">c</span> <span class="k">else</span> <span class="i" onmouseover="showTip(event, 'fun0244', 141)" onmouseout="hideTip(event, 'fun0244', 141)">parser</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0251', 142)" onmouseout="hideTip(event, 'fun0251', 142)">Zero</span>()
    )

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0252', 143)" onmouseout="hideTip(event, 'fun0252', 143)">tcParser'</span> <span class="i" onmouseover="showTip(event, 'fun0217', 144)" onmouseout="hideTip(event, 'fun0217', 144)">c</span> <span class="o">=</span>  <span class="i" onmouseover="showTip(event, 'fun0248', 145)" onmouseout="hideTip(event, 'fun0248', 145)">satisfyParser'</span> ((<span class="o">=</span>) <span class="i" onmouseover="showTip(event, 'fun0217', 146)" onmouseout="hideTip(event, 'fun0217', 146)">c</span>)
</pre>
</div>
<p>&nbsp;</p>
<p>No news here, just a plain straight rewrite using the new function notations.</p>
<h3>Let the magic begin</h3>
<p>So far so good, but it can get tiring very quickly if we need to keep calling all those binds, returns and zeros,&nbsp;to build more capable parsers -&nbsp;so let&rsquo;s let the F# compiler do it for us!</p>
<p>I actually tricked you into creating the <em>ParserBuilder</em> class for &ldquo;organization purposes&rdquo; only, I did have a hidden goal&hellip; It turns out that, whenever the compiler sees a class type with some especial methods like the ones in <em>ParserBuilder</em>, it does some under-the-covers magic and provides us with some well-deserved syntactic sugar (interestingly enough, you will see that this new syntax allows us to write code that looks very similar to the imperative style, go figure...). For example, <em>satisfyParser&rsquo;&nbsp;</em> and <em>tcParser&rsquo;</em> can now be written as (renaming them to sat and tChar respectively):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0253', 147)" onmouseout="hideTip(event, 'fun0253', 147)">sat</span> <span class="i" onmouseover="showTip(event, 'fun0246', 148)" onmouseout="hideTip(event, 'fun0246', 148)">pred</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 149)" onmouseout="hideTip(event, 'fun0244', 149)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0217', 150)" onmouseout="hideTip(event, 'fun0217', 150)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0216', 151)" onmouseout="hideTip(event, 'fun0216', 151)">item</span>
    <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun0246', 152)" onmouseout="hideTip(event, 'fun0246', 152)">pred</span> <span class="i" onmouseover="showTip(event, 'fun0217', 153)" onmouseout="hideTip(event, 'fun0217', 153)">c</span> <span class="k">then</span> <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0217', 154)" onmouseout="hideTip(event, 'fun0217', 154)">c</span>
}

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0254', 155)" onmouseout="hideTip(event, 'fun0254', 155)">tChar</span> <span class="i" onmouseover="showTip(event, 'fun0217', 156)" onmouseout="hideTip(event, 'fun0217', 156)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0253', 157)" onmouseout="hideTip(event, 'fun0253', 157)">sat</span> ((<span class="o">=</span>) <span class="i" onmouseover="showTip(event, 'fun0217', 158)" onmouseout="hideTip(event, 'fun0217', 158)">c</span>)
</pre>
</div>
<p>&nbsp;</p>
<p>This is very neat, isn&rsquo;t it? They call it&nbsp;<span style="text-decoration: underline;">computation expressions</span>, but I prefer to call it "the magical syntactic sugar that allows me to easily sequence and compose computations". It is exactly the same behavior as before, but with some magical sugar from the compiler: <em>let! c = item</em> is&nbsp;replaced by <em>parser.Bind(item, fun c -&gt; ...)</em>; everything after the <em>let!</em> line is added to the continuation function of the&nbsp;<em>Bind</em> call, and finally <em>return c</em> is replaced by&nbsp;the call to <em>parser.Return c.</em>&nbsp;Note how &ldquo;sweet&rdquo; this notation is: we don&rsquo;t even need an <em>else</em> branch in the conditional test above, the compiler is attaching the call to the <em>Zero()</em> for us! You can find all special methods for the "builder types" (like our <em>ParserBuilder</em> class) on <a title="Computation Expressions (F#)" href="http://msdn.microsoft.com/en-us/library/dd233182.aspx" target="_blank">this MSDN entry</a>.</p>
<p>If you reached this far, I have a suprise for you! You may not have noticed, but <strong>you&rsquo;ve just built your very first <span style="text-decoration: underline;">Parser Monad</span></strong>! Congrats! It didn&rsquo;t even hurt, did it?</p>
<p>No kidding! F#&rsquo;s computation expression is F#&rsquo;s syntax for monads, so applying some logic here: a parser using computation expression is a parser using monad, which is a Parser Monad! Cool, now go and tell everyone you&rsquo;ve conquered the &ldquo;Monadic Parser Badge&rdquo; :-).</p>
<p>Using this new notation, let&rsquo;s port to F# the remaining parsers from Erik&rsquo;s paper: a couple of &ldquo;choice combinators&rdquo;, the "recursion combinators" and finally the "lexical combinators".</p>
<h4>Choice Combinators</h4>
<p><strong>Plus and Or Parsers</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="c">///</span><span class="c"> </span><span class="c">Concatenates</span><span class="c"> </span><span class="c">the</span><span class="c"> </span><span class="c">results</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">applying</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span><span class="c"> </span><span class="c">and</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">q</span>
<span class="k">let</span> (<span class="o">&lt;+&gt;</span>) <span class="i" onmouseover="showTip(event, 'fun0231', 159)" onmouseout="hideTip(event, 'fun0231', 159)">p</span> <span class="i" onmouseover="showTip(event, 'fun0255', 160)" onmouseout="hideTip(event, 'fun0255', 160)">q</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 161)" onmouseout="hideTip(event, 'fun0210', 161)">Parser</span> (<span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 162)" onmouseout="hideTip(event, 'fun026', 162)">cs</span> <span class="k">-&gt;</span> (<span class="i" onmouseover="showTip(event, 'fun0218', 163)" onmouseout="hideTip(event, 'fun0218', 163)">parse</span> <span class="i" onmouseover="showTip(event, 'fun0231', 164)" onmouseout="hideTip(event, 'fun0231', 164)">p</span> <span class="i" onmouseover="showTip(event, 'fun026', 165)" onmouseout="hideTip(event, 'fun026', 165)">cs</span>) <span class="o">@</span> (<span class="i" onmouseover="showTip(event, 'fun0218', 166)" onmouseout="hideTip(event, 'fun0218', 166)">parse</span> <span class="i" onmouseover="showTip(event, 'fun0255', 167)" onmouseout="hideTip(event, 'fun0255', 167)">q</span> <span class="i" onmouseover="showTip(event, 'fun026', 168)" onmouseout="hideTip(event, 'fun026', 168)">cs</span>))
<span class="c">///</span><span class="c"> </span><span class="c">Applies</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">q</span><span class="c"> </span><span class="c">and</span><span class="c"> </span><span class="c">returns</span><span class="c"> </span><span class="c">at</span><span class="c"> </span><span class="c">most</span><span class="c"> </span><span class="c">one</span><span class="c"> </span><span class="c">result</span>
<span class="k">let</span> (<span class="o">&lt;|&gt;</span>) <span class="i" onmouseover="showTip(event, 'fun0231', 169)" onmouseout="hideTip(event, 'fun0231', 169)">p</span> <span class="i" onmouseover="showTip(event, 'fun0255', 170)" onmouseout="hideTip(event, 'fun0255', 170)">q</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0210', 171)" onmouseout="hideTip(event, 'fun0210', 171)">Parser</span> (<span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun026', 172)" onmouseout="hideTip(event, 'fun026', 172)">cs</span> <span class="k">-&gt;</span> 
    <span class="k">match</span> (<span class="i" onmouseover="showTip(event, 'fun0218', 173)" onmouseout="hideTip(event, 'fun0218', 173)">parse</span> (<span class="i" onmouseover="showTip(event, 'fun0231', 174)" onmouseout="hideTip(event, 'fun0231', 174)">p</span> <span class="o">&lt;+&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0255', 175)" onmouseout="hideTip(event, 'fun0255', 175)">q</span>) <span class="i" onmouseover="showTip(event, 'fun026', 176)" onmouseout="hideTip(event, 'fun026', 176)">cs</span>) <span class="k">with</span>
    | []    <span class="k">-&gt;</span> []
    | <span class="i" onmouseover="showTip(event, 'fun0256', 177)" onmouseout="hideTip(event, 'fun0256', 177)">x</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun0257', 178)" onmouseout="hideTip(event, 'fun0257', 178)">xs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun0256', 179)" onmouseout="hideTip(event, 'fun0256', 179)">x</span>]
)
</pre>
</div>
<p>&nbsp;</p>
<p>The &ldquo;plus&rdquo; parser (<em>&lt;+&gt;</em>) sequences two parsers (<em>p</em> and <em>q</em>) on the same input string and concatenates the resulting lists. We use this &ldquo;plus&rdquo; parser to build an &ldquo;or&rdquo; parser which returns at most one result: the result of applying <em>p</em> if it succeeds, or the result of applying <em>q</em> if <em>p</em> fails (or empty list if both fail).</p>
<p>The somewhat weird <em>&lt;+&gt;</em>&nbsp; and <em>&lt;|&gt;</em> function names allow us to use them in an infix manner, so we can write things like: <em>aParser &lt;+&gt; bParser</em>&nbsp; or <em>cParser &lt;|&gt; dParser</em>.</p>
<p>Let&rsquo;s run them on F# interactive to better understand their behavior:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'T' &lt;+&gt; tChar 'T');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [('T', ['e'; 's'; 't']); ('T', ['e'; 's'; 't'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'T' &lt;|&gt; tChar 'T');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 's'; 't'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'T' &lt;+&gt; tChar 'Z');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 's'; 't'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'T' &lt;|&gt; tChar 'Z');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 's'; 't'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'Z' &lt;|&gt; tChar 'T');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 's'; 't'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'Z' &lt;+&gt; tChar 'T');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = [('T', ['e'; 's'; 't'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; parse (tChar 'Z' &lt;+&gt; tChar 'Z');;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list = []</span></p>
<h4>Recursion Combinators</h4>
<p><strong>Text Parser</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="c">///</span><span class="c"> </span><span class="c">Given</span><span class="c"> </span><span class="c">a</span><span class="c"> </span><span class="c">char</span><span class="c"> </span><span class="c">list,</span><span class="c"> </span><span class="c">returns</span><span class="c"> </span><span class="c">a</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">that</span><span class="c"> </span><span class="c">parsers</span><span class="c"> </span><span class="c">it</span>
<span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fun0258', 180)" onmouseout="hideTip(event, 'fun0258', 180)">text</span> <span class="o">=</span> <span class="k">function</span>
    | []  <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0244', 181)" onmouseout="hideTip(event, 'fun0244', 181)">parser</span> { <span class="k">return</span> [] }
    | <span class="i" onmouseover="showTip(event, 'fun0217', 182)" onmouseout="hideTip(event, 'fun0217', 182)">c</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun026', 183)" onmouseout="hideTip(event, 'fun026', 183)">cs</span> <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0244', 184)" onmouseout="hideTip(event, 'fun0244', 184)">parser</span> { 
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0254', 185)" onmouseout="hideTip(event, 'fun0254', 185)">tChar</span> <span class="i" onmouseover="showTip(event, 'fun0217', 186)" onmouseout="hideTip(event, 'fun0217', 186)">c</span>
        <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0258', 187)" onmouseout="hideTip(event, 'fun0258', 187)">text</span> <span class="i" onmouseover="showTip(event, 'fun026', 188)" onmouseout="hideTip(event, 'fun026', 188)">cs</span>
        <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0217', 189)" onmouseout="hideTip(event, 'fun0217', 189)">c</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun026', 190)" onmouseout="hideTip(event, 'fun026', 190)">cs</span> 
    }
</pre>
</div>
<p>&nbsp;</p>
<p>The text parser is very similar to the stringParser we built in the last post: it takes a char list as parameter and builds a parser that is capable of parsing that specific char list:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; let thisParser = text (s2cs "This");;</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">val thisParser : char list Parser = Parser &lt;fun:Bind@40&gt;</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "This is a test" |&gt; s2cs |&gt; parse thisParser;;</span><br /><span style="font-family: courier new,courier;">val it : (char list * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [(['T'; 'h'; 'i'; 's'], [' '; 'i'; 's'; ' '; 'a'; ' '; 't'; 'e'; 's'; 't'])]</span></p>
<p><strong>Many and Many1 Parsers</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="c">///</span><span class="c"> </span><span class="c">Combines</span><span class="c"> </span><span class="c">many</span><span class="c"> </span><span class="c">(0</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">more)</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span>
<span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fun0259', 191)" onmouseout="hideTip(event, 'fun0259', 191)">many</span> <span class="i" onmouseover="showTip(event, 'fun0231', 192)" onmouseout="hideTip(event, 'fun0231', 192)">p</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fun0260', 193)" onmouseout="hideTip(event, 'fun0260', 193)">many1</span> <span class="i" onmouseover="showTip(event, 'fun0231', 194)" onmouseout="hideTip(event, 'fun0231', 194)">p</span>) <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0244', 195)" onmouseout="hideTip(event, 'fun0244', 195)">parser</span> { <span class="k">return</span> [] }
<span class="c">///</span><span class="c"> </span><span class="c">Combines</span><span class="c"> </span><span class="c">at</span><span class="c"> </span><span class="c">least</span><span class="c"> </span><span class="c">one</span><span class="c"> </span><span class="c">(1</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">more)</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span>
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fun0260', 196)" onmouseout="hideTip(event, 'fun0260', 196)">many1</span> <span class="i" onmouseover="showTip(event, 'fun0231', 197)" onmouseout="hideTip(event, 'fun0231', 197)">p</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun0244', 198)" onmouseout="hideTip(event, 'fun0244', 198)">parser</span> { 
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0261', 199)" onmouseout="hideTip(event, 'fun0261', 199)">r</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0231', 200)" onmouseout="hideTip(event, 'fun0231', 200)">p</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0262', 201)" onmouseout="hideTip(event, 'fun0262', 201)">rs</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 202)" onmouseout="hideTip(event, 'fun0259', 202)">many</span> <span class="i" onmouseover="showTip(event, 'fun0231', 203)" onmouseout="hideTip(event, 'fun0231', 203)">p</span>
        <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0261', 204)" onmouseout="hideTip(event, 'fun0261', 204)">r</span><span class="o">::</span><span class="i">rs</span>
    } 
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>Many</em> and its brother <em>many1</em> are really useful parsers when you need to sequence zero to many, or one to many, applications of a parser. For example, remember the homework from the last post, how to parse &ldquo;fun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp; 7&rdquo;? We can now use <em>many</em>/<em>many1</em> to easily consume all those white spaces from the input string:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">type</span> <span class="i" onmouseover="showTip(event, 'fun0272', 253)" onmouseout="hideTip(event, 'fun0272', 253)">FunAST</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0273', 254)" onmouseout="hideTip(event, 'fun0273', 254)">Fun</span> <span class="k">of</span> (<span class="i" onmouseover="showTip(event, 'fun0211', 255)" onmouseout="hideTip(event, 'fun0211', 255)">char</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun0274', 256)" onmouseout="hideTip(event, 'fun0274', 256)">int</span>)
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0275', 257)" onmouseout="hideTip(event, 'fun0275', 257)">funParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 258)" onmouseout="hideTip(event, 'fun0244', 258)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0258', 259)" onmouseout="hideTip(event, 'fun0258', 259)">text</span> (<span class="i" onmouseover="showTip(event, 'fun022', 260)" onmouseout="hideTip(event, 'fun022', 260)">s2cs</span> <span class="s">"</span><span class="s">fun</span><span class="s">"</span>)
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0260', 261)" onmouseout="hideTip(event, 'fun0260', 261)">many1</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 262)" onmouseout="hideTip(event, 'fun0254', 262)">tChar</span> <span class="s">' '</span>)
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0273', 263)" onmouseout="hideTip(event, 'fun0273', 263)">Fun</span>
}
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0276', 264)" onmouseout="hideTip(event, 'fun0276', 264)">identParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 265)" onmouseout="hideTip(event, 'fun0244', 265)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0277', 266)" onmouseout="hideTip(event, 'fun0277', 266)">ident</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0216', 267)" onmouseout="hideTip(event, 'fun0216', 267)">item</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 268)" onmouseout="hideTip(event, 'fun0259', 268)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 269)" onmouseout="hideTip(event, 'fun0254', 269)">tChar</span> <span class="s">' '</span>)
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0277', 270)" onmouseout="hideTip(event, 'fun0277', 270)">ident</span>
}
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0278', 271)" onmouseout="hideTip(event, 'fun0278', 271)">digitParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 272)" onmouseout="hideTip(event, 'fun0244', 272)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0279', 273)" onmouseout="hideTip(event, 'fun0279', 273)">d</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0253', 274)" onmouseout="hideTip(event, 'fun0253', 274)">sat</span> <span class="i" onmouseover="showTip(event, 'fun0280', 275)" onmouseout="hideTip(event, 'fun0280', 275)">Char</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0281', 276)" onmouseout="hideTip(event, 'fun0281', 276)">IsDigit</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 277)" onmouseout="hideTip(event, 'fun0259', 277)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 278)" onmouseout="hideTip(event, 'fun0254', 278)">tChar</span> <span class="s">' '</span>)
    <span class="k">return</span> (<span class="i" onmouseover="showTip(event, 'fun0279', 279)" onmouseout="hideTip(event, 'fun0279', 279)">d</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0282', 280)" onmouseout="hideTip(event, 'fun0282', 280)">string</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0283', 281)" onmouseout="hideTip(event, 'fun0283', 281)">Int32</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0284', 282)" onmouseout="hideTip(event, 'fun0284', 282)">Parse</span>)
}
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0285', 283)" onmouseout="hideTip(event, 'fun0285', 283)">equalParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 284)" onmouseout="hideTip(event, 'fun0244', 284)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0217', 285)" onmouseout="hideTip(event, 'fun0217', 285)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0254', 286)" onmouseout="hideTip(event, 'fun0254', 286)">tChar</span> <span class="s">'='</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 287)" onmouseout="hideTip(event, 'fun0259', 287)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 288)" onmouseout="hideTip(event, 'fun0254', 288)">tChar</span> <span class="s">' '</span>)
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0217', 289)" onmouseout="hideTip(event, 'fun0217', 289)">c</span>
}
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0286', 290)" onmouseout="hideTip(event, 'fun0286', 290)">funLangParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 291)" onmouseout="hideTip(event, 'fun0244', 291)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 292)" onmouseout="hideTip(event, 'fun0259', 292)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 293)" onmouseout="hideTip(event, 'fun0254', 293)">tChar</span> <span class="s">' '</span>)
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0287', 294)" onmouseout="hideTip(event, 'fun0287', 294)">funFunc</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0275', 295)" onmouseout="hideTip(event, 'fun0275', 295)">funParser</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0277', 296)" onmouseout="hideTip(event, 'fun0277', 296)">ident</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0276', 297)" onmouseout="hideTip(event, 'fun0276', 297)">identParser</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0285', 298)" onmouseout="hideTip(event, 'fun0285', 298)">equalParser</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0288', 299)" onmouseout="hideTip(event, 'fun0288', 299)">digit</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0278', 300)" onmouseout="hideTip(event, 'fun0278', 300)">digitParser</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0287', 301)" onmouseout="hideTip(event, 'fun0287', 301)">funFunc</span>(<span class="i" onmouseover="showTip(event, 'fun0277', 302)" onmouseout="hideTip(event, 'fun0277', 302)">ident</span>, <span class="i">digit</span>)
}
</pre>
</div>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp; 7" |&gt; s2cs |&gt; parse funLangParser;;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST * char list) list = [(Fun ('z', 7), [])]</span><br /><span style="font-family: courier new,courier;">&gt; "fun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " |&gt; s2cs |&gt; parse funLangParser;;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST * char list) list = [(Fun ('z', 7), [])]</span><br /><span style="font-family: courier new,courier;">&gt; "fail&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " |&gt; s2cs |&gt; parse funLangParser;;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST * char list) list = []</span></p>
<p><strong>Sepby and Sepby1 Parsers</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="c">///</span><span class="c"> </span><span class="c">Combines</span><span class="c"> </span><span class="c">0</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">more</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span><span class="c"> </span><span class="c">separated</span><span class="c"> </span><span class="c">by</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">sep</span>
<span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fun0263', 205)" onmouseout="hideTip(event, 'fun0263', 205)">sepby</span> <span class="i" onmouseover="showTip(event, 'fun0231', 206)" onmouseout="hideTip(event, 'fun0231', 206)">p</span> <span class="i" onmouseover="showTip(event, 'fun0264', 207)" onmouseout="hideTip(event, 'fun0264', 207)">sep</span> <span class="o">=</span>  (<span class="i" onmouseover="showTip(event, 'fun0265', 208)" onmouseout="hideTip(event, 'fun0265', 208)">sepby1</span> <span class="i" onmouseover="showTip(event, 'fun0231', 209)" onmouseout="hideTip(event, 'fun0231', 209)">p</span> <span class="i" onmouseover="showTip(event, 'fun0264', 210)" onmouseout="hideTip(event, 'fun0264', 210)">sep</span>) <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0244', 211)" onmouseout="hideTip(event, 'fun0244', 211)">parser</span> { <span class="k">return</span> [] }
<span class="c">///</span><span class="c"> </span><span class="c">Combines</span><span class="c"> </span><span class="c">1</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">more</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span><span class="c"> </span><span class="c">separated</span><span class="c"> </span><span class="c">by</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">sep</span>
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fun0265', 212)" onmouseout="hideTip(event, 'fun0265', 212)">sepby1</span> <span class="i" onmouseover="showTip(event, 'fun0231', 213)" onmouseout="hideTip(event, 'fun0231', 213)">p</span> <span class="i" onmouseover="showTip(event, 'fun0264', 214)" onmouseout="hideTip(event, 'fun0264', 214)">sep</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun0244', 215)" onmouseout="hideTip(event, 'fun0244', 215)">parser</span> {
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0261', 216)" onmouseout="hideTip(event, 'fun0261', 216)">r</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0231', 217)" onmouseout="hideTip(event, 'fun0231', 217)">p</span>
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0262', 218)" onmouseout="hideTip(event, 'fun0262', 218)">rs</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 219)" onmouseout="hideTip(event, 'fun0259', 219)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0244', 220)" onmouseout="hideTip(event, 'fun0244', 220)">parser</span> { 
            <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0264', 221)" onmouseout="hideTip(event, 'fun0264', 221)">sep</span>
            <span class="k">return!</span> <span class="i" onmouseover="showTip(event, 'fun0231', 222)" onmouseout="hideTip(event, 'fun0231', 222)">p</span>
        })
        <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0261', 223)" onmouseout="hideTip(event, 'fun0261', 223)">r</span><span class="o">::</span><span class="i">rs</span>
    }
</pre>
</div>
<p>&nbsp;</p>
<p>The next pair of recursion combinators is <em>sepby</em> and <em>sepby1</em> &ndash; they are also very useful when you have a parsing pattern, e.g. things &ldquo;separated&rdquo; by other things. They both take two parsers as parameters, a parser to be repeatedly sequenced, and a &ldquo;separation&rdquo; parser, that is thrown away. Note how they rely on <em>many</em> and <em>&lt;|&gt;</em> in their implementation. To test them, let&rsquo;s pretend we can now have entries like this in our fun language:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">fun x = 1;</span><br /><span style="font-family: courier new,courier;">fun z = 9;</span></p>
<p>We could easily parse them by using the sepby/sepby1 parsers:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0289', 303)" onmouseout="hideTip(event, 'fun0289', 303)">sepParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 304)" onmouseout="hideTip(event, 'fun0244', 304)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 305)" onmouseout="hideTip(event, 'fun0259', 305)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 306)" onmouseout="hideTip(event, 'fun0254', 306)">tChar</span> <span class="s">' '</span>)
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0217', 307)" onmouseout="hideTip(event, 'fun0217', 307)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0254', 308)" onmouseout="hideTip(event, 'fun0254', 308)">tChar</span> <span class="s">';'</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0217', 309)" onmouseout="hideTip(event, 'fun0217', 309)">c</span>
}

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0290', 310)" onmouseout="hideTip(event, 'fun0290', 310)">improvedLangParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0265', 311)" onmouseout="hideTip(event, 'fun0265', 311)">sepby1</span> <span class="i" onmouseover="showTip(event, 'fun0286', 312)" onmouseout="hideTip(event, 'fun0286', 312)">funLangParser</span> <span class="i" onmouseover="showTip(event, 'fun0289', 313)" onmouseout="hideTip(event, 'fun0289', 313)">sepParser</span>
</pre>
</div>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun z = 1;" |&gt; s2cs |&gt; parse improvedLangParser;;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST list * char list) list = [([Fun ('z', 1)], [';'])]</span><br /><span style="font-family: courier new,courier;">&gt; "fun z = 1;&nbsp;&nbsp; fun y = 2; fun&nbsp;&nbsp;&nbsp;&nbsp; w&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp; 3" |&gt; s2cs |&gt; parse improvedLangParser;;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST list * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [([Fun ('z', 1); Fun ('y', 2); Fun ('w', 3)], [])]</span></p>
<p><strong>Chainl and Chainl1 Parsers</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="c">///</span><span class="c"> </span><span class="c">Chain</span><span class="c"> </span><span class="c">0</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">more</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span><span class="c"> </span><span class="c">separated</span><span class="c"> </span><span class="c">by</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">op</span>
<span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fun0266', 224)" onmouseout="hideTip(event, 'fun0266', 224)">chainl</span> <span class="i" onmouseover="showTip(event, 'fun0231', 225)" onmouseout="hideTip(event, 'fun0231', 225)">p</span> <span class="i" onmouseover="showTip(event, 'fun0267', 226)" onmouseout="hideTip(event, 'fun0267', 226)">op</span> <span class="i" onmouseover="showTip(event, 'fun0243', 227)" onmouseout="hideTip(event, 'fun0243', 227)">a</span> <span class="o">=</span> (<span class="i" onmouseover="showTip(event, 'fun0268', 228)" onmouseout="hideTip(event, 'fun0268', 228)">chainl1</span>  <span class="i" onmouseover="showTip(event, 'fun0231', 229)" onmouseout="hideTip(event, 'fun0231', 229)">p</span> <span class="i" onmouseover="showTip(event, 'fun0267', 230)" onmouseout="hideTip(event, 'fun0267', 230)">op</span>) <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0244', 231)" onmouseout="hideTip(event, 'fun0244', 231)">parser</span> { <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0243', 232)" onmouseout="hideTip(event, 'fun0243', 232)">a</span> }
<span class="c">///</span><span class="c"> </span><span class="c">Chain</span><span class="c"> </span><span class="c">1</span><span class="c"> </span><span class="c">or</span><span class="c"> </span><span class="c">more</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">p</span><span class="c"> </span><span class="c">separated</span><span class="c"> </span><span class="c">by</span><span class="c"> </span><span class="c">applications</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">parser</span><span class="c"> </span><span class="c">op</span>
<span class="k">and</span> <span class="i" onmouseover="showTip(event, 'fun0268', 233)" onmouseout="hideTip(event, 'fun0268', 233)">chainl1</span> <span class="i" onmouseover="showTip(event, 'fun0231', 234)" onmouseout="hideTip(event, 'fun0231', 234)">p</span> <span class="i" onmouseover="showTip(event, 'fun0267', 235)" onmouseout="hideTip(event, 'fun0267', 235)">op</span> <span class="o">=</span>  
    <span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fun0269', 236)" onmouseout="hideTip(event, 'fun0269', 236)">rest</span> <span class="i" onmouseover="showTip(event, 'fun0261', 237)" onmouseout="hideTip(event, 'fun0261', 237)">r</span> <span class="o">=</span> 
        <span class="i" onmouseover="showTip(event, 'fun0244', 238)" onmouseout="hideTip(event, 'fun0244', 238)">parser</span> {
            <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0270', 239)" onmouseout="hideTip(event, 'fun0270', 239)">f</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0267', 240)" onmouseout="hideTip(event, 'fun0267', 240)">op</span>
            <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0271', 241)" onmouseout="hideTip(event, 'fun0271', 241)">r'</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0231', 242)" onmouseout="hideTip(event, 'fun0231', 242)">p</span>
            <span class="k">return!</span> <span class="i" onmouseover="showTip(event, 'fun0269', 243)" onmouseout="hideTip(event, 'fun0269', 243)">rest</span> (<span class="i" onmouseover="showTip(event, 'fun0270', 244)" onmouseout="hideTip(event, 'fun0270', 244)">f</span> <span class="i" onmouseover="showTip(event, 'fun0261', 245)" onmouseout="hideTip(event, 'fun0261', 245)">r</span> <span class="i">r'</span>)
        } <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0244', 246)" onmouseout="hideTip(event, 'fun0244', 246)">parser</span> {<span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0261', 247)" onmouseout="hideTip(event, 'fun0261', 247)">r</span>}

    <span class="i" onmouseover="showTip(event, 'fun0244', 248)" onmouseout="hideTip(event, 'fun0244', 248)">parser</span> { <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0243', 249)" onmouseout="hideTip(event, 'fun0243', 249)">a</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0231', 250)" onmouseout="hideTip(event, 'fun0231', 250)">p</span> <span class="k">in</span> <span class="k">return!</span> <span class="i" onmouseover="showTip(event, 'fun0269', 251)" onmouseout="hideTip(event, 'fun0269', 251)">rest</span> <span class="i" onmouseover="showTip(event, 'fun0243', 252)" onmouseout="hideTip(event, 'fun0243', 252)">a</span> }
</pre>
</div>
<p>&nbsp;</p>
<p>Finally the last pair of recursion combinators is <em>chainl</em> and <em>chainl1</em> &ndash; they are a little bit trickier though, they parse repeated applications of parser <em>p</em> separated by applications of parser <em>op</em>, similar to sepby; however, <em>op</em> is a <span style="text-decoration: underline;">left associative operator parser</span> (ohh&hellip; I&rsquo;ve got to use that phrase tonight at the dinner table!). If <em>p</em> is an <em>&lsquo;a Parser</em>, then <em>op</em> will be an <em>(&lsquo;a -&gt; &lsquo;a -&gt; &lsquo;a) Parser</em>&hellip;</p>
<p>Improving even more our fun language, let&rsquo;s now support code like &ldquo;fun x = 1 + 1&rdquo; by using the <em>chainl</em> and <em>&lt;|&gt;</em> parsers:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0291', 314)" onmouseout="hideTip(event, 'fun0291', 314)">sumParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 315)" onmouseout="hideTip(event, 'fun0244', 315)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0254', 316)" onmouseout="hideTip(event, 'fun0254', 316)">tChar</span> <span class="s">'+'</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 317)" onmouseout="hideTip(event, 'fun0259', 317)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 318)" onmouseout="hideTip(event, 'fun0254', 318)">tChar</span> <span class="s">' '</span>)
    <span class="k">return</span> (<span class="o">+</span>)
}
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0292', 319)" onmouseout="hideTip(event, 'fun0292', 319)">digitParser'</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun0268', 320)" onmouseout="hideTip(event, 'fun0268', 320)">chainl1</span> <span class="i" onmouseover="showTip(event, 'fun0278', 321)" onmouseout="hideTip(event, 'fun0278', 321)">digitParser</span> <span class="i" onmouseover="showTip(event, 'fun0291', 322)" onmouseout="hideTip(event, 'fun0291', 322)">sumParser</span> 
    <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0278', 323)" onmouseout="hideTip(event, 'fun0278', 323)">digitParser</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0293', 324)" onmouseout="hideTip(event, 'fun0293', 324)">funLangParser'</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 325)" onmouseout="hideTip(event, 'fun0244', 325)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 326)" onmouseout="hideTip(event, 'fun0259', 326)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0254', 327)" onmouseout="hideTip(event, 'fun0254', 327)">tChar</span> <span class="s">' '</span>)
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0287', 328)" onmouseout="hideTip(event, 'fun0287', 328)">funFunc</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0275', 329)" onmouseout="hideTip(event, 'fun0275', 329)">funParser</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0277', 330)" onmouseout="hideTip(event, 'fun0277', 330)">ident</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0276', 331)" onmouseout="hideTip(event, 'fun0276', 331)">identParser</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0285', 332)" onmouseout="hideTip(event, 'fun0285', 332)">equalParser</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0288', 333)" onmouseout="hideTip(event, 'fun0288', 333)">digit</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0292', 334)" onmouseout="hideTip(event, 'fun0292', 334)">digitParser'</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0287', 335)" onmouseout="hideTip(event, 'fun0287', 335)">funFunc</span>(<span class="i" onmouseover="showTip(event, 'fun0277', 336)" onmouseout="hideTip(event, 'fun0277', 336)">ident</span>, <span class="i">digit</span>)
}

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0294', 337)" onmouseout="hideTip(event, 'fun0294', 337)">improvedLangParser'</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0265', 338)" onmouseout="hideTip(event, 'fun0265', 338)">sepby1</span> <span class="i" onmouseover="showTip(event, 'fun0293', 339)" onmouseout="hideTip(event, 'fun0293', 339)">funLangParser'</span> <span class="i" onmouseover="showTip(event, 'fun0289', 340)" onmouseout="hideTip(event, 'fun0289', 340)">sepParser</span>
</pre>
</div>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x=1+ 1; fun z = 9 + 1 + 2 + 3; fun w = 5" |&gt; s2cs |&gt; parse improvedLangParser';;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST list * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [([Fun ('x', 2); Fun ('z', 15); Fun ('w', 5)], [])]</span></p>
<p>Hover over the new <em>sumParser</em> parser and you will notice it is a <em>(int -&gt; int -&gt; int) Parser</em> and it returns a left associative operator (+). We use it in the new <em>digitParser&rsquo;</em> by chaining <em>digitParser</em> with it. We then&nbsp;apply <em>&lt;|&gt;</em> to try both options, <em>e.g.</em>, a digit in our language can be a sum of digits (<em>chainl1 digitParser sumParser</em>), or (<em>&lt;|&gt;</em>) a single digit (<em>digitParser</em>): at most one of these two parsers must return a value. It is also important to note the order used to in the <em>&lt;|&gt;</em> call, had <em>digitParser</em> been used first (e.g. &ldquo;<em>digitParser &lt;|&gt; chainl1 digitParser sumParser</em>&rdquo;), <em>chainl1</em> would never have a chance to be applied, because <em>digitParser</em> would always return the first digit of the sum.</p>
<h4>Lexical Combinators</h4>
<p>These are very simple parsers but yet very handy. They will implement some of the functionality we&rsquo;ve been hardcoding so far.</p>
<p><strong>Space Parser</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0295', 341)" onmouseout="hideTip(event, 'fun0295', 341)">isSpace</span> <span class="o">=</span>
    <span class="c">//</span><span class="c"> </span><span class="c">list</span><span class="c"> </span><span class="c">of</span><span class="c"> </span><span class="c">"space"</span><span class="c"> </span><span class="c">chars</span><span class="c"> </span><span class="c">based</span><span class="c"> </span><span class="c">on</span><span class="c"> </span>
    <span class="c">//</span><span class="c"> </span><span class="c">http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Char.html#v:isSpace</span>
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun0296', 342)" onmouseout="hideTip(event, 'fun0296', 342)">cs</span> <span class="o">=</span> [<span class="s">' '</span>; <span class="s">'\t'</span>; <span class="s">'\n'</span>; <span class="s">'\r'</span>; <span class="s">'\f'</span>; <span class="s">'\v'</span>] <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0297', 343)" onmouseout="hideTip(event, 'fun0297', 343)">Set</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0298', 344)" onmouseout="hideTip(event, 'fun0298', 344)">ofList</span>
    <span class="i" onmouseover="showTip(event, 'fun0296', 345)" onmouseout="hideTip(event, 'fun0296', 345)">cs</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0299', 346)" onmouseout="hideTip(event, 'fun0299', 346)">Contains</span>
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02100', 347)" onmouseout="hideTip(event, 'fun02100', 347)">space</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0259', 348)" onmouseout="hideTip(event, 'fun0259', 348)">many</span> (<span class="i" onmouseover="showTip(event, 'fun0253', 349)" onmouseout="hideTip(event, 'fun0253', 349)">sat</span> <span class="i" onmouseover="showTip(event, 'fun0295', 350)" onmouseout="hideTip(event, 'fun0295', 350)">isSpace</span>)
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>space</em> comes to get us out of the business of parsing whitespaces. We build a predicate function (<em>isSpace</em>) using a set of chars we want to consider as whitespaces (I&rsquo;m basing mine on the same ones used by Haskell&rsquo;s <em>Data.Char.isSpace</em>), and then we create a parser that is capable of &ldquo;parsing many characters that satisfy the <em>isSpace</em> predicate&rdquo; (I like how the function implementation easily translates to English: <em>many (sat isSpace)</em>).</p>
<p><strong>Token Parser</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02101', 351)" onmouseout="hideTip(event, 'fun02101', 351)">token</span> <span class="i" onmouseover="showTip(event, 'fun0231', 352)" onmouseout="hideTip(event, 'fun0231', 352)">p</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 353)" onmouseout="hideTip(event, 'fun0244', 353)">parser</span> { 
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0261', 354)" onmouseout="hideTip(event, 'fun0261', 354)">r</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0231', 355)" onmouseout="hideTip(event, 'fun0231', 355)">p</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02100', 356)" onmouseout="hideTip(event, 'fun02100', 356)">space</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0261', 357)" onmouseout="hideTip(event, 'fun0261', 357)">r</span>
}
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>token</em> takes a parser, sequences it and the space parser, returning the result of the application of the input parser; in other words, it will apply a parser you give it and remove all white space afterwards, returning the parsed thing.</p>
<p><strong>Symbol Parser</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02102', 358)" onmouseout="hideTip(event, 'fun02102', 358)">symb</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0258', 359)" onmouseout="hideTip(event, 'fun0258', 359)">text</span> <span class="o">&gt;</span><span class="o">&gt;</span> <span class="i" onmouseover="showTip(event, 'fun02101', 360)" onmouseout="hideTip(event, 'fun02101', 360)">token</span>
</pre>
</div>
<p><em></em>&nbsp;</p>
<p><em>symb</em> takes it further by composing a <em>text</em> parser and&nbsp;a <em>token</em> parser (for the less &ldquo;functional composition&rdquo; savvy, it could be written as <em>let symb cs = token (text cs)</em> :-). This little guy will allow us to parse a specific string (a literal, for example)&nbsp;with whitespace clean up afterwards&hellip; and it will be used a lot.</p>
<p><strong>Apply Parser</strong></p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02103', 361)" onmouseout="hideTip(event, 'fun02103', 361)">apply</span> <span class="i" onmouseover="showTip(event, 'fun0231', 362)" onmouseout="hideTip(event, 'fun0231', 362)">p</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0218', 363)" onmouseout="hideTip(event, 'fun0218', 363)">parse</span> (<span class="i" onmouseover="showTip(event, 'fun0244', 364)" onmouseout="hideTip(event, 'fun0244', 364)">parser</span> {
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02100', 365)" onmouseout="hideTip(event, 'fun02100', 365)">space</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0261', 366)" onmouseout="hideTip(event, 'fun0261', 366)">r</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0231', 367)" onmouseout="hideTip(event, 'fun0231', 367)">p</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0261', 368)" onmouseout="hideTip(event, 'fun0261', 368)">r</span>
})
</pre>
</div>
<p>&nbsp;</p>
<p>Last but not least, <em>apply</em> is used to initiate the parsing computation: it calls <em>parse</em>&nbsp;(the extraction function we defined earlier)&nbsp;on a parser that cleans up the initial whitespace (if any) of the string to be parsed and applies the parser you give it to the rest of the string.</p>
<h3>Final fun language parser</h3>
<p>Let&rsquo;s take all these parser combinators and build yet another, but this&nbsp;time really final,&nbsp;version of our fun language parser. Just because we now have more building blocks in our bag, let&rsquo;s add the capability of accepting more than one digit at time (&ldquo;fun a = 123 + 321&rdquo;), by using <em>many1</em> in the digit parser (see below):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02104', 369)" onmouseout="hideTip(event, 'fun02104', 369)">funP</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 370)" onmouseout="hideTip(event, 'fun0244', 370)">parser</span> { <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02102', 371)" onmouseout="hideTip(event, 'fun02102', 371)">symb</span> (<span class="i" onmouseover="showTip(event, 'fun022', 372)" onmouseout="hideTip(event, 'fun022', 372)">s2cs</span> <span class="s">"</span><span class="s">fun</span><span class="s">"</span>) <span class="k">in</span> <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0273', 373)" onmouseout="hideTip(event, 'fun0273', 373)">Fun</span> }
<span class="k">let</span>

<span class="i" onmouseover="showTip(event, 'fun02105', 374)" onmouseout="hideTip(event, 'fun02105', 374)">identP</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 375)" onmouseout="hideTip(event, 'fun0244', 375)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0217', 376)" onmouseout="hideTip(event, 'fun0217', 376)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02101', 377)" onmouseout="hideTip(event, 'fun02101', 377)">token</span> <span class="i" onmouseover="showTip(event, 'fun0216', 378)" onmouseout="hideTip(event, 'fun0216', 378)">item</span>
    <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02102', 379)" onmouseout="hideTip(event, 'fun02102', 379)">symb</span> [<span class="s">'='</span>]
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun0217', 380)" onmouseout="hideTip(event, 'fun0217', 380)">c</span>
}

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02106', 381)" onmouseout="hideTip(event, 'fun02106', 381)">sumP</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 382)" onmouseout="hideTip(event, 'fun0244', 382)">parser</span> { <span class="k">let!</span> _ <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02102', 383)" onmouseout="hideTip(event, 'fun02102', 383)">symb</span> [<span class="s">'+'</span>] <span class="k">in</span> <span class="k">return</span> (<span class="o">+</span>) }

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02107', 384)" onmouseout="hideTip(event, 'fun02107', 384)">digitP</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02108', 385)" onmouseout="hideTip(event, 'fun02108', 385)">digitP'</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 386)" onmouseout="hideTip(event, 'fun0244', 386)">parser</span> {
        <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun02109', 387)" onmouseout="hideTip(event, 'fun02109', 387)">ds</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02101', 388)" onmouseout="hideTip(event, 'fun02101', 388)">token</span> (<span class="i" onmouseover="showTip(event, 'fun0260', 389)" onmouseout="hideTip(event, 'fun0260', 389)">many1</span> (<span class="i" onmouseover="showTip(event, 'fun0253', 390)" onmouseout="hideTip(event, 'fun0253', 390)">sat</span> <span class="i" onmouseover="showTip(event, 'fun0280', 391)" onmouseout="hideTip(event, 'fun0280', 391)">Char</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0281', 392)" onmouseout="hideTip(event, 'fun0281', 392)">IsDigit</span>))
        <span class="k">return</span>  (<span class="i">ds</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun025', 393)" onmouseout="hideTip(event, 'fun025', 393)">cs2s</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun0283', 394)" onmouseout="hideTip(event, 'fun0283', 394)">Int32</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun0284', 395)" onmouseout="hideTip(event, 'fun0284', 395)">Parse</span>)
    }
    <span class="i" onmouseover="showTip(event, 'fun0268', 396)" onmouseout="hideTip(event, 'fun0268', 396)">chainl1</span> <span class="i" onmouseover="showTip(event, 'fun02108', 397)" onmouseout="hideTip(event, 'fun02108', 397)">digitP'</span> <span class="i" onmouseover="showTip(event, 'fun02106', 398)" onmouseout="hideTip(event, 'fun02106', 398)">sumP</span>
    <span class="o">&lt;|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun02108', 399)" onmouseout="hideTip(event, 'fun02108', 399)">digitP'</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02110', 400)" onmouseout="hideTip(event, 'fun02110', 400)">funLangP</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0244', 401)" onmouseout="hideTip(event, 'fun0244', 401)">parser</span> {
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun02111', 402)" onmouseout="hideTip(event, 'fun02111', 402)">f</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02104', 403)" onmouseout="hideTip(event, 'fun02104', 403)">funP</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun0277', 404)" onmouseout="hideTip(event, 'fun0277', 404)">ident</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02105', 405)" onmouseout="hideTip(event, 'fun02105', 405)">identP</span>
    <span class="k">let!</span> <span class="i" onmouseover="showTip(event, 'fun02112', 406)" onmouseout="hideTip(event, 'fun02112', 406)">d</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun02107', 407)" onmouseout="hideTip(event, 'fun02107', 407)">digitP</span>
    <span class="k">return</span> <span class="i" onmouseover="showTip(event, 'fun02111', 408)" onmouseout="hideTip(event, 'fun02111', 408)">f</span>(<span class="i" onmouseover="showTip(event, 'fun0277', 409)" onmouseout="hideTip(event, 'fun0277', 409)">ident</span>, <span class="i" onmouseover="showTip(event, 'fun02112', 410)" onmouseout="hideTip(event, 'fun02112', 410)">d</span>)
}

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02113', 411)" onmouseout="hideTip(event, 'fun02113', 411)">finalLangP</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun0265', 412)" onmouseout="hideTip(event, 'fun0265', 412)">sepby1</span> <span class="i" onmouseover="showTip(event, 'fun02110', 413)" onmouseout="hideTip(event, 'fun02110', 413)">funLangP</span> (<span class="i" onmouseover="showTip(event, 'fun02102', 414)" onmouseout="hideTip(event, 'fun02102', 414)">symb</span> [<span class="s">';'</span>])
</pre>
</div>
<p>&nbsp;</p>
<p>Do you remember the runParser function?&nbsp; We can update it to use the <em>apply</em> parser (so white space in the beginning of the string is taken care of), and test our final parser:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02114', 415)" onmouseout="hideTip(event, 'fun02114', 415)">runParser</span> <span class="i" onmouseover="showTip(event, 'fun0231', 416)" onmouseout="hideTip(event, 'fun0231', 416)">p</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun022', 417)" onmouseout="hideTip(event, 'fun022', 417)">s2cs</span> <span class="o">&gt;</span><span class="o">&gt;</span>
    <span class="i" onmouseover="showTip(event, 'fun02103', 418)" onmouseout="hideTip(event, 'fun02103', 418)">apply</span> <span class="i" onmouseover="showTip(event, 'fun0231', 419)" onmouseout="hideTip(event, 'fun0231', 419)">p</span> <span class="o">&gt;</span><span class="o">&gt;</span>
    <span class="k">function</span>
        | [] <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun02115', 420)" onmouseout="hideTip(event, 'fun02115', 420)">failwith</span> <span class="s">"</span><span class="s">Error</span><span class="s"> </span><span class="s">parsing</span><span class="s"> </span><span class="s">string</span><span class="s">"</span>
        | (<span class="i" onmouseover="showTip(event, 'fun02116', 421)" onmouseout="hideTip(event, 'fun02116', 421)">result</span>,_)<span class="o">::</span>_ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun02116', 422)" onmouseout="hideTip(event, 'fun02116', 422)">result</span>
        
</pre>
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun02117', 423)" onmouseout="hideTip(event, 'fun02117', 423)">doesItReallyWork</span> () <span class="o">=</span> 
    <span class="s">"</span><span class="s"> </span><span class="s">fun</span><span class="s"> </span><span class="s">x</span><span class="s">=</span><span class="s">99</span><span class="s">+</span><span class="s"> </span><span class="s">1</span><span class="s">;</span><span class="s"> </span>
<span class="s"> </span><span class="s">fun</span><span class="s"> </span><span class="s">z</span><span class="s"> </span><span class="s">=</span><span class="s"> </span><span class="s">9</span><span class="s"> </span><span class="s">+</span><span class="s"> </span><span class="s">1</span><span class="s"> </span><span class="s">+</span><span class="s"> </span><span class="s">2</span><span class="s"> </span><span class="s">+</span><span class="s"> </span><span class="s">3</span><span class="s">;</span><span class="s"> </span>
<span class="s"> </span><span class="s">fun</span><span class="s"> </span><span class="s">w</span><span class="s"> </span><span class="s">=</span><span class="s"> </span><span class="s">57</span><span class="s">"</span>
    <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun02114', 424)" onmouseout="hideTip(event, 'fun02114', 424)">runParser</span> <span class="i" onmouseover="showTip(event, 'fun02113', 425)" onmouseout="hideTip(event, 'fun02113', 425)">finalLangP</span>
</pre>
</div>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; doesItReallyWork ();;</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">val it : FunAST list = <span style="background-color: #ffff99;">[Fun ('x', 100); Fun ('z', 15); Fun ('w', 57)]</span></span></p>
<p>Success!!!</p>
<h3>Wrapping up</h3>
<p>We learned that, by moving the handcrafted parsers we built in part 1 to using Computation Expressions, we were able to build parsers in a more succinct and expressive way, thanks to the syntax sugar provided by F#. Using this new trick, we ported all parser combinators in Erik/Graham's paper from Haskell to F#, creating a basic set of general purpose parsers.</p>
<p>We are now ready to move to our next challenge: build&nbsp;the JSON parser (finally!). Enough of the good-for-nothing fun language &ndash; I hope it did serve its purpose though.</p>
<p>See you next and let me know your comments!</p>
<h3>Parsing JSON the fun way series</h3>
<p>&bull; <a title="Part 1: Building a parser from scratch with Dr. Seuss help (part 1)" href="http://bit.ly/qPBllg">Part 1: Building a parser from scratch with Dr. Seuss help (part 1) <br /></a>&bull; <a title="Part 2: Tricking you into Parser Monads (it's not going to hurt, I promise)" href="http://bit.ly/rl3swK">Part 2: Tricking you into Parser Monads (it's not going to hurt, I promise)<br /></a>&bull; <a title="Part 3: The JSON Parser Monad" href="http://bit.ly/rSIjjP">Part 3: The JSON Parser Monad</a></p>
<p>&nbsp;</p>
<!-- HTML code for ToolTips -->
<div id="fun021" class="tip">namespace System</div>
<div id="fun022" class="tip">val s2cs : (seq&lt;'a&gt; -&gt; 'a list)<br /><br />Full name: FunLang02.s2cs</div>
<div id="fun023" class="tip">Multiple items <br />module List<br /><br />from Microsoft.FSharp.Collections <br /><br />--------------------<br /> <br />type List&lt;'T&gt; =<br />&nbsp;&nbsp;| ( [] )<br />&nbsp;&nbsp;| ( :: ) of 'T * 'T list<br />&nbsp;&nbsp;with<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.IEnumerable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Head : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsEmpty : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Item : index:int -&gt; 'T with get<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Tail : 'T list<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Cons : head:'T * tail:'T list -&gt; 'T list<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Empty : 'T list<br />&nbsp;&nbsp;end<br /><br />Full name: Microsoft.FSharp.Collections.List&lt;_&gt;<br /><br />&nbsp;&nbsp;type: List&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'T&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun024" class="tip">val ofSeq : seq&lt;'T&gt; -&gt; 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.ofSeq</div>
<div id="fun025" class="tip">val cs2s : char list -&gt; String<br /><br />Full name: FunLang02.cs2s</div>
<div id="fun026" class="tip">val cs : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun027" class="tip">type String =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte * int * int * System.Text.Encoding -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char [] * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Chars : int -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Contains : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : int * char [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string * bool * System.Globalization.CultureInfo -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEnumerator : unit -&gt; System.CharEnumerator<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Insert : int * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsNormalized : unit -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsNormalized : System.Text.NormalizationForm -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Normalize : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Normalize : System.Text.NormalizationForm -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadLeft : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadLeft : int * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadRight : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadRight : int * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Replace : char * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Replace : string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * int -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : string [] * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * int * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : string [] * int * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string * bool * System.Globalization.CultureInfo -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Substring : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Substring : int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToCharArray : unit -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToCharArray : int * int -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLower : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLower : System.Globalization.CultureInfo -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLowerInvariant : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpper : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpper : System.Globalization.CultureInfo -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpperInvariant : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Trim : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Trim : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member TrimEnd : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member TrimStart : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val Empty : string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * bool -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * System.Globalization.CultureInfo * System.Globalization.CompareOptions -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * bool * System.Globalization.CultureInfo -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * bool -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * bool * System.Globalization.CultureInfo -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * System.Globalization.CultureInfo * System.Globalization.CompareOptions -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CompareOrdinal : string * string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CompareOrdinal : string * int * string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat&lt;'T&gt; : System.Collections.Generic.IEnumerable&lt;'T&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : System.Collections.Generic.IEnumerable&lt;string&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string * string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Equals : string * string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Equals : string * string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : System.IFormatProvider * string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Intern : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsInterned : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNullOrEmpty : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNullOrWhiteSpace : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * string [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join&lt;'T&gt; : string * System.Collections.Generic.IEnumerable&lt;'T&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * System.Collections.Generic.IEnumerable&lt;string&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * string [] * int * int -&gt; string<br />&nbsp;&nbsp;end<br /><br />Full name: System.String<br /><br />&nbsp;&nbsp;type: String<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fun028" class="tip">type Array =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : System.Array * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : System.Array * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEnumerator : unit -&gt; System.Collections.IEnumerator<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLength : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLongLength : int -&gt; int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLowerBound : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetUpperBound : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int [] -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 [] -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int * int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 * int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int * int * int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 * int64 * int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member Initialize : unit -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsFixedSize : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsReadOnly : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSynchronized : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LongLength : int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member Rank : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SyncRoot : obj<br />&nbsp;&nbsp;&nbsp;&nbsp;static member AsReadOnly&lt;'T&gt; : 'T [] -&gt; System.Collections.ObjectModel.ReadOnlyCollection&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * obj * System.Collections.IComparer -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * 'T * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * int * int * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * int * int * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * int * int * obj * System.Collections.IComparer -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * int * int * 'T * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Clear : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConstrainedCopy : System.Array * int * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertAll&lt;'TInput,'TOutput&gt; : 'TInput [] * System.Converter&lt;'TInput,'TOutput&gt; -&gt; 'TOutput []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * System.Array * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * System.Array * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * int * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * int64 * System.Array * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int64 [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int [] * int [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int * int * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Exists&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Find&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindAll&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * int * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLast&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * int * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ForEach&lt;'T&gt; : 'T [] * System.Action&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Resize&lt;'T&gt; : 'T [] * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Reverse : System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Reverse : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * System.Comparison&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * System.Collections.Generic.IComparer&lt;'TKey&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * int * int * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * int * int * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * int * int * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * int * int * System.Collections.Generic.IComparer&lt;'TKey&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TrueForAll&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Array<br /><br />&nbsp;&nbsp;type: Array<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: Collections.IList<br />&nbsp;&nbsp;implements: Collections.ICollection<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable</div>
<div id="fun029" class="tip">val ofList : 'T list -&gt; 'T []<br /><br />Full name: Microsoft.FSharp.Collections.Array.ofList</div>
<div id="fun0210" class="tip">Multiple items <br />union case Parser.Parser: (char list -&gt; ('a * char list) list) -&gt; 'a Parser <br /><br />--------------------<br /> <br />type 'a Parser = | Parser of (char list -&gt; ('a * char list) list)<br /><br />Full name: FunLang02.Parser&lt;_&gt;</div>
<div id="fun0211" class="tip">Multiple items <br />val char : 'T -&gt; char (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.char <br /><br />--------------------<br /> <br />type char = Char<br /><br />Full name: Microsoft.FSharp.Core.char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0212" class="tip">type 'T list = List&lt;'T&gt;<br /><br />Full name: Microsoft.FSharp.Collections.list&lt;_&gt;<br /><br />&nbsp;&nbsp;type: 'T list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'T&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0213" class="tip">val cParser : 'a list -&gt; ('a * 'a list) list<br /><br />Full name: FunLang02.cParser</div>
<div id="fun0214" class="tip">val c : 'a</div>
<div id="fun0215" class="tip">val cs : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0216" class="tip">val item : char Parser<br /><br />Full name: FunLang02.item</div>
<div id="fun0217" class="tip">val c : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0218" class="tip">val parse : 'a Parser -&gt; (char list -&gt; ('a * char list) list)<br /><br />Full name: FunLang02.parse</div>
<div id="fun0219" class="tip">val p : (char list -&gt; ('a * char list) list)</div>
<div id="fun0220" class="tip">val returnParser : 'a -&gt; 'b -&gt; ('a * 'b) list<br /><br />Full name: FunLang02.returnParser</div>
<div id="fun0221" class="tip">val thing : 'a</div>
<div id="fun0222" class="tip">val cs : 'b</div>
<div id="fun0223" class="tip">val zeroParser : unit -&gt; 'a -&gt; 'b list<br /><br />Full name: FunLang02.zeroParser</div>
<div id="fun0224" class="tip">val bindParser : (char list -&gt; ('a * char list) list) * ('a -&gt; char list -&gt; ('b * char list) list) -&gt; char list -&gt; ('b * char list) list<br /><br />Full name: FunLang02.bindParser</div>
<div id="fun0225" class="tip">val f : ('a -&gt; char list -&gt; ('b * char list) list)</div>
<div id="fun0226" class="tip">val c' : 'a</div>
<div id="fun0227" class="tip">val cs' : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0228" class="tip">val returnParser' : 'a -&gt; 'a Parser<br /><br />Full name: FunLang02.returnParser'</div>
<div id="fun0229" class="tip">val zeroParser' : unit -&gt; 'a Parser<br /><br />Full name: FunLang02.zeroParser'</div>
<div id="fun0230" class="tip">val bindParser' : 'a Parser * ('a -&gt; 'b Parser) -&gt; 'b Parser<br /><br />Full name: FunLang02.bindParser'</div>
<div id="fun0231" class="tip">val p : 'a Parser</div>
<div id="fun0232" class="tip">val f : ('a -&gt; 'b Parser)</div>
<div id="fun0233" class="tip">type ParserBuilder =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;new : unit -&gt; ParserBuilder<br />&nbsp;&nbsp;&nbsp;&nbsp;member Bind : p:'c Parser * f:('c -&gt; 'd Parser) -&gt; 'd Parser<br />&nbsp;&nbsp;&nbsp;&nbsp;member Return : a:'e -&gt; 'e Parser<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReturnFrom : a:'a -&gt; 'a<br />&nbsp;&nbsp;&nbsp;&nbsp;member Zero : unit -&gt; 'b Parser<br />&nbsp;&nbsp;end<br /><br />Full name: FunLang02.ParserBuilder</div>
<div id="fun0234" class="tip">val x : ParserBuilder</div>
<div id="fun0235" class="tip">member ParserBuilder.Return : a:'e -&gt; 'e Parser<br /><br />Full name: FunLang02.ParserBuilder.Return</div>
<div id="fun0236" class="tip">val a : 'e</div>
<div id="fun0237" class="tip">member ParserBuilder.Bind : p:'c Parser * f:('c -&gt; 'd Parser) -&gt; 'd Parser<br /><br />Full name: FunLang02.ParserBuilder.Bind</div>
<div id="fun0238" class="tip">val p : 'c Parser</div>
<div id="fun0239" class="tip">val f : ('c -&gt; 'd Parser)</div>
<div id="fun0240" class="tip">val c' : 'c</div>
<div id="fun0241" class="tip">member ParserBuilder.Zero : unit -&gt; 'b Parser<br /><br />Full name: FunLang02.ParserBuilder.Zero</div>
<div id="fun0242" class="tip">member ParserBuilder.ReturnFrom : a:'a -&gt; 'a<br /><br />Full name: FunLang02.ParserBuilder.ReturnFrom</div>
<div id="fun0243" class="tip">val a : 'a</div>
<div id="fun0244" class="tip">val parser : ParserBuilder<br /><br />Full name: FunLang02.parser</div>
<div id="fun0245" class="tip">val satisfyParser : (char -&gt; bool) -&gt; (char list -&gt; (char * char list) list)<br /><br />Full name: FunLang02.satisfyParser</div>
<div id="fun0246" class="tip">val pred : (char -&gt; bool)</div>
<div id="fun0247" class="tip">val tcParser : char -&gt; (char list -&gt; (char * char list) list)<br /><br />Full name: FunLang02.tcParser</div>
<div id="fun0248" class="tip">val satisfyParser' : (char -&gt; bool) -&gt; char Parser<br /><br />Full name: FunLang02.satisfyParser'</div>
<div id="fun0249" class="tip">member ParserBuilder.Bind : p:'c Parser * f:('c -&gt; 'd Parser) -&gt; 'd Parser</div>
<div id="fun0250" class="tip">member ParserBuilder.Return : a:'e -&gt; 'e Parser</div>
<div id="fun0251" class="tip">member ParserBuilder.Zero : unit -&gt; 'b Parser</div>
<div id="fun0252" class="tip">val tcParser' : char -&gt; char Parser<br /><br />Full name: FunLang02.tcParser'</div>
<div id="fun0253" class="tip">val sat : (char -&gt; bool) -&gt; char Parser<br /><br />Full name: FunLang02.sat</div>
<div id="fun0254" class="tip">val tChar : char -&gt; char Parser<br /><br />Full name: FunLang02.tChar</div>
<div id="fun0255" class="tip">val q : 'a Parser</div>
<div id="fun0256" class="tip">val x : 'a * char list</div>
<div id="fun0257" class="tip">val xs : ('a * char list) list<br /><br />&nbsp;&nbsp;type: ('a * char list) list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a * char list&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a * char list&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0258" class="tip">val text : char list -&gt; char list Parser<br /><br />Full name: FunLang02.text <br /><br /><em>Given a char list, returns a parser that parsers it</em></div>
<div id="fun0259" class="tip">val many : 'a Parser -&gt; 'a list Parser<br /><br />Full name: FunLang02.many <br /><br /><em>Combines many (0 or more) applications of parser p</em></div>
<div id="fun0260" class="tip">val many1 : 'a Parser -&gt; 'a list Parser<br /><br />Full name: FunLang02.many1 <br /><br /><em>Combines at least one (1 or more) applications of parser p</em></div>
<div id="fun0261" class="tip">val r : 'a</div>
<div id="fun0262" class="tip">val rs : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0263" class="tip">val sepby : 'a Parser -&gt; 'b Parser -&gt; 'a list Parser<br /><br />Full name: FunLang02.sepby <br /><br /><em>Combines 0 or more applications of parser p separated by parser sep</em></div>
<div id="fun0264" class="tip">val sep : 'b Parser</div>
<div id="fun0265" class="tip">val sepby1 : 'a Parser -&gt; 'b Parser -&gt; 'a list Parser<br /><br />Full name: FunLang02.sepby1 <br /><br /><em>Combines 1 or more applications of parser p separated by parser sep</em></div>
<div id="fun0266" class="tip">val chainl : 'a Parser -&gt; ('a -&gt; 'a -&gt; 'a) Parser -&gt; 'a -&gt; 'a Parser<br /><br />Full name: FunLang02.chainl <br /><br /><em>Chain 0 or more applications of parser p separated by applications of parser op</em></div>
<div id="fun0267" class="tip">val op : ('a -&gt; 'a -&gt; 'a) Parser</div>
<div id="fun0268" class="tip">val chainl1 : 'a Parser -&gt; ('a -&gt; 'a -&gt; 'a) Parser -&gt; 'a Parser<br /><br />Full name: FunLang02.chainl1 <br /><br /><em>Chain 1 or more applications of parser p separated by applications of parser op</em></div>
<div id="fun0269" class="tip">val rest : ('a -&gt; 'a Parser)</div>
<div id="fun0270" class="tip">val f : ('a -&gt; 'a -&gt; 'a)</div>
<div id="fun0271" class="tip">val r' : 'a</div>
<div id="fun0272" class="tip">type FunAST = | Fun of (char * int)<br /><br />Full name: FunLang02.FunAST<br /><br />&nbsp;&nbsp;type: FunAST<br />&nbsp;&nbsp;implements: IEquatable&lt;FunAST&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;FunAST&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fun0273" class="tip">union case FunAST.Fun: char * int -&gt; FunAST</div>
<div id="fun0274" class="tip">Multiple items <br />val int : 'T -&gt; int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int <br /><br />--------------------<br /> <br />type int&lt;'Measure&gt; = int<br /><br />Full name: Microsoft.FSharp.Core.int&lt;_&gt;<br /><br />&nbsp;&nbsp;type: int&lt;'Measure&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IComparable&lt;int&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;inherits: ValueType<br /> <br /><br />--------------------<br /> <br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0275" class="tip">val funParser : (char * int -&gt; FunAST) Parser<br /><br />Full name: FunLang02.funParser</div>
<div id="fun0276" class="tip">val identParser : char Parser<br /><br />Full name: FunLang02.identParser</div>
<div id="fun0277" class="tip">val ident : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0278" class="tip">val digitParser : int Parser<br /><br />Full name: FunLang02.digitParser</div>
<div id="fun0279" class="tip">val d : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0280" class="tip">type Char =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : char<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertFromUtf32 : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertToUtf32 : char * char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertToUtf32 : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetNumericValue : char -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetNumericValue : string * int -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetUnicodeCategory : char -&gt; System.Globalization.UnicodeCategory<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetUnicodeCategory : string * int -&gt; System.Globalization.UnicodeCategory<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsControl : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsControl : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsDigit : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsDigit : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsHighSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsHighSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetter : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetter : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetterOrDigit : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetterOrDigit : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLowSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLowSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLower : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLower : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNumber : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNumber : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPunctuation : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPunctuation : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSeparator : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSeparator : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogatePair : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogatePair : char * char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSymbol : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSymbol : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsUpper : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsUpper : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsWhiteSpace : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsWhiteSpace : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLower : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLower : char * System.Globalization.CultureInfo -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLowerInvariant : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToString : char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpper : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpper : char * System.Globalization.CultureInfo -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpperInvariant : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * char -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Char<br /><br />&nbsp;&nbsp;type: Char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0281" class="tip">Multiple overloads <br />Char.IsDigit(c: char) : bool <br />Char.IsDigit(s: string, index: int) : bool</div>
<div id="fun0282" class="tip">Multiple items <br />val string : 'T -&gt; string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string <br /><br />--------------------<br /> <br />type string = String<br /><br />Full name: Microsoft.FSharp.Core.string<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fun0283" class="tip">type Int32 =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string * System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : int<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.IFormatProvider -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * System.Globalization.NumberStyles * System.IFormatProvider * int -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Int32<br /><br />&nbsp;&nbsp;type: Int32<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0284" class="tip">Multiple overloads <br />Int32.Parse(s: string) : int <br />Int32.Parse(s: string, provider: IFormatProvider) : int <br />Int32.Parse(s: string, style: Globalization.NumberStyles) : int <br />Int32.Parse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider) : int</div>
<div id="fun0285" class="tip">val equalParser : char Parser<br /><br />Full name: FunLang02.equalParser</div>
<div id="fun0286" class="tip">val funLangParser : FunAST Parser<br /><br />Full name: FunLang02.funLangParser</div>
<div id="fun0287" class="tip">val funFunc : (char * int -&gt; FunAST)</div>
<div id="fun0288" class="tip">val digit : int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun0289" class="tip">val sepParser : char Parser<br /><br />Full name: FunLang02.sepParser</div>
<div id="fun0290" class="tip">val improvedLangParser : FunAST list Parser<br /><br />Full name: FunLang02.improvedLangParser</div>
<div id="fun0291" class="tip">val sumParser : (int -&gt; int -&gt; int) Parser<br /><br />Full name: FunLang02.sumParser</div>
<div id="fun0292" class="tip">val digitParser' : int Parser<br /><br />Full name: FunLang02.digitParser'</div>
<div id="fun0293" class="tip">val funLangParser' : FunAST Parser<br /><br />Full name: FunLang02.funLangParser'</div>
<div id="fun0294" class="tip">val improvedLangParser' : FunAST list Parser<br /><br />Full name: FunLang02.improvedLangParser'</div>
<div id="fun0295" class="tip">val isSpace : (char -&gt; bool)<br /><br />Full name: FunLang02.isSpace</div>
<div id="fun0296" class="tip">val cs : Set&lt;char&gt;<br /><br />&nbsp;&nbsp;type: Set&lt;char&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.Generic.ICollection&lt;char&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0297" class="tip">Multiple items <br />module Set<br /><br />from Microsoft.FSharp.Collections <br /><br />--------------------<br /> <br />type Set&lt;'T (requires comparison)&gt; =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;interface IComparable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.IEnumerable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.ICollection&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;new : elements:seq&lt;'T&gt; -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Add : value:'T -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Contains : value:'T -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;override Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsProperSubsetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsProperSupersetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSubsetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSupersetOf : otherSet:Set&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : value:'T -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Count : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsEmpty : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member MaximumElement : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;member MinimumElement : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ( + ) : set1:Set&lt;'T&gt; * set2:Set&lt;'T&gt; -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ( - ) : set1:Set&lt;'T&gt; * set2:Set&lt;'T&gt; -&gt; Set&lt;'T&gt;<br />&nbsp;&nbsp;end<br /><br />Full name: Microsoft.FSharp.Collections.Set&lt;_&gt;<br /><br />&nbsp;&nbsp;type: Set&lt;'T&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.Generic.ICollection&lt;'T&gt;<br />&nbsp;&nbsp;implements: seq&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun0298" class="tip">val ofList : 'T list -&gt; Set&lt;'T&gt; (requires comparison)<br /><br />Full name: Microsoft.FSharp.Collections.Set.ofList</div>
<div id="fun0299" class="tip">member Set.Contains : value:'T -&gt; bool</div>
<div id="fun02100" class="tip">val space : char list Parser<br /><br />Full name: FunLang02.space</div>
<div id="fun02101" class="tip">val token : 'a Parser -&gt; 'a Parser<br /><br />Full name: FunLang02.token</div>
<div id="fun02102" class="tip">val symb : (char list -&gt; char list Parser)<br /><br />Full name: FunLang02.symb</div>
<div id="fun02103" class="tip">val apply : 'a Parser -&gt; (char list -&gt; ('a * char list) list)<br /><br />Full name: FunLang02.apply</div>
<div id="fun02104" class="tip">val funP : (char * int -&gt; FunAST) Parser<br /><br />Full name: FunLang02.funP</div>
<div id="fun02105" class="tip">val identP : char Parser<br /><br />Full name: FunLang02.identP</div>
<div id="fun02106" class="tip">val sumP : (int -&gt; int -&gt; int) Parser<br /><br />Full name: FunLang02.sumP</div>
<div id="fun02107" class="tip">val digitP : int Parser<br /><br />Full name: FunLang02.digitP</div>
<div id="fun02108" class="tip">val digitP' : int Parser</div>
<div id="fun02109" class="tip">val ds : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun02110" class="tip">val funLangP : FunAST Parser<br /><br />Full name: FunLang02.funLangP</div>
<div id="fun02111" class="tip">val f : (char * int -&gt; FunAST)</div>
<div id="fun02112" class="tip">val d : int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun02113" class="tip">val finalLangP : FunAST list Parser<br /><br />Full name: FunLang02.finalLangP</div>
<div id="fun02114" class="tip">val runParser : 'a Parser -&gt; (seq&lt;char&gt; -&gt; 'a)<br /><br />Full name: FunLang02.runParser</div>
<div id="fun02115" class="tip">val failwith : string -&gt; 'T<br /><br />Full name: Microsoft.FSharp.Core.Operators.failwith</div>
<div id="fun02116" class="tip">val result : 'a</div>
<div id="fun02117" class="tip">val doesItReallyWork : unit -&gt; FunAST list<br /><br />Full name: FunLang02.doesItReallyWork</div>]]></content:encoded>
    </item>
    <item>
      <title>Parsing JSON the fun way: monadic parsers, records and type providers (Part 1)</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-1</link>
      <pubDate>Tue, 11 Oct 2011 14:56:00 GMT</pubDate>
      <dc:creator><![CDATA[Zandoná]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2011/10/11/parsing-json-the-fun-way-monadic-parsers-records-and-type-providers-part-1/</guid>
      <description><![CDATA[Image it is late in the night, you have some JSON data on your hands that needs to be parsed, and...]]></description>
      <content:encoded><![CDATA[<p>Image it is late in the night, you have some JSON data on your hands that needs to be parsed, and all you have is the F# compiler&hellip; how would you go about parsing it? I was in that situation the other night and was faced with two options: rely on the well tested .NET libraries or venture myself into magical woods of monadic parsing. I ended up going with the fun option!</p>
<h3>The boring parsing approach...</h3>
<p>The &ldquo;boring&rdquo; way of parsing JSON is, as expected, the simplest approach: you just need to define a Record that will hold the parsed data, decorate it with <em>DataContract/DataMember</em> attributes, and use the<em> DataContractJsonSerializer</em> class from the <em>System.Runtime.Serialization.Json</em> namespace to deserialize your JSON string into an F# Record. For example, enter the following snippet in F# Interactive and you will get a nice &ldquo;Person&rdquo; object from the JSON string.</p>
<div class="snippet">
<pre class="fssnip"><span class="l"> 1: </span><span class="prep">#r</span> <span class="s">"</span><span class="s">System</span><span class="s">.</span><span class="s">Runtime</span><span class="s">.</span><span class="s">Serialization</span><span class="s">.</span><span class="s">dll</span><span class="s">"</span>
<span class="l"> 2: </span><span class="k">open</span> <span class="i" onmouseover="showTip(event, 'fstips1', 1)" onmouseout="hideTip(event, 'fstips1', 1)">System</span>
<span class="l"> 3: </span><span class="k">open</span> <span class="i" onmouseover="showTip(event, 'fstips1', 2)" onmouseout="hideTip(event, 'fstips1', 2)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips2', 3)" onmouseout="hideTip(event, 'fstips2', 3)">IO</span>
<span class="l"> 4: </span><span class="k">open</span> <span class="i" onmouseover="showTip(event, 'fstips1', 4)" onmouseout="hideTip(event, 'fstips1', 4)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips3', 5)" onmouseout="hideTip(event, 'fstips3', 5)">Runtime</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips4', 6)" onmouseout="hideTip(event, 'fstips4', 6)">Serialization</span>
<span class="l"> 5: </span><span class="k">open</span> <span class="i" onmouseover="showTip(event, 'fstips1', 7)" onmouseout="hideTip(event, 'fstips1', 7)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips5', 8)" onmouseout="hideTip(event, 'fstips5', 8)">Text</span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>[&lt;<span class="i" onmouseover="showTip(event, 'fstips6', 9)" onmouseout="hideTip(event, 'fstips6', 9)">DataContract</span>&gt;]
<span class="l"> 8: </span><span class="k">type</span> <span class="i" onmouseover="showTip(event, 'fstips7', 10)" onmouseout="hideTip(event, 'fstips7', 10)">Person</span> <span class="o">=</span> {
<span class="l"> 9: </span>    [&lt;<span class="i">field</span><span class="o">:</span> <span class="i" onmouseover="showTip(event, 'fstips8', 11)" onmouseout="hideTip(event, 'fstips8', 11)">DataMember</span>(<span class="i">Name</span> <span class="o">=</span> <span class="s">"</span><span class="s">Name</span><span class="s">"</span>)&gt;]
<span class="l">10: </span>    <span class="i" onmouseover="showTip(event, 'fstips9', 12)" onmouseout="hideTip(event, 'fstips9', 12)">Name</span> <span class="o">:</span> <span class="i" onmouseover="showTip(event, 'fstips10', 13)" onmouseout="hideTip(event, 'fstips10', 13)">string</span>
<span class="l">11: </span>    [&lt;<span class="i">field</span><span class="o">:</span> <span class="i" onmouseover="showTip(event, 'fstips8', 14)" onmouseout="hideTip(event, 'fstips8', 14)">DataMember</span>(<span class="i" onmouseover="showTip(event, 'fstips9', 15)" onmouseout="hideTip(event, 'fstips9', 15)">Name</span> <span class="o">=</span> <span class="s">"</span><span class="s">Phone</span><span class="s">"</span>)&gt;]
<span class="l">12: </span>    <span class="i" onmouseover="showTip(event, 'fstips11', 16)" onmouseout="hideTip(event, 'fstips11', 16)">Phone</span> <span class="o">:</span> <span class="i" onmouseover="showTip(event, 'fstips12', 17)" onmouseout="hideTip(event, 'fstips12', 17)">int</span>
<span class="l">13: </span>}
<span class="l">14: </span>
<span class="l">15: </span><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips13', 18)" onmouseout="hideTip(event, 'fstips13', 18)">jsonString</span> <span class="o">=</span> <span class="s">"</span><span class="s">{</span>
<span class="l">16: </span><span class="s"> </span><span class="s">\"</span><span class="s">Name</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">\"</span><span class="s">Fernando</span><span class="s">\"</span><span class="s">,</span>
<span class="l">17: </span><span class="s"> </span><span class="s">\"</span><span class="s">Phone</span><span class="s">\"</span><span class="s">:</span><span class="s"> </span><span class="s">123456789</span>
<span class="l">18: </span><span class="s"> </span><span class="s">}</span><span class="s">"</span>
<span class="l">19: </span>
<span class="l">20: </span><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips14', 19)" onmouseout="hideTip(event, 'fstips14', 19)">js</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips15', 20)" onmouseout="hideTip(event, 'fstips15', 20)">Json</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips16', 21)" onmouseout="hideTip(event, 'fstips16', 21)">DataContractJsonSerializer</span>(<span class="i" onmouseover="showTip(event, 'fstips17', 22)" onmouseout="hideTip(event, 'fstips17', 22)">typeof</span><span class="o">&lt;</span><span class="i" onmouseover="showTip(event, 'fstips7', 23)" onmouseout="hideTip(event, 'fstips7', 23)">Person</span><span class="o">&gt;</span>)
<span class="l">21: </span><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips18', 24)" onmouseout="hideTip(event, 'fstips18', 24)">buffer</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips13', 25)" onmouseout="hideTip(event, 'fstips13', 25)">jsonString</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips19', 26)" onmouseout="hideTip(event, 'fstips19', 26)">Encoding</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips20', 27)" onmouseout="hideTip(event, 'fstips20', 27)">UTF8</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips21', 28)" onmouseout="hideTip(event, 'fstips21', 28)">GetBytes</span>
<span class="l">22: </span><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fstips22', 29)" onmouseout="hideTip(event, 'fstips22', 29)">person</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fstips14', 30)" onmouseout="hideTip(event, 'fstips14', 30)">js</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips23', 31)" onmouseout="hideTip(event, 'fstips23', 31)">ReadObject</span>(<span class="k">new</span> <span class="i" onmouseover="showTip(event, 'fstips24', 32)" onmouseout="hideTip(event, 'fstips24', 32)">MemoryStream</span>(<span class="i" onmouseover="showTip(event, 'fstips18', 33)" onmouseout="hideTip(event, 'fstips18', 33)">buffer</span>)) <span class="o">:?&gt;</span> <span class="i" onmouseover="showTip(event, 'fstips7', 34)" onmouseout="hideTip(event, 'fstips7', 34)">Person</span>
<span class="l">23: </span>
<span class="l">24: </span><span class="i" onmouseover="showTip(event, 'fstips25', 35)" onmouseout="hideTip(event, 'fstips25', 35)">printfn</span> <span class="s">"</span><span class="s">Name</span><span class="s">:</span><span class="s"> </span><span class="s">%</span><span class="s">s</span><span class="s">,</span><span class="s"> </span><span class="s">Phone</span><span class="s"> </span><span class="s">number</span><span class="s">:</span><span class="s"> </span><span class="s">%</span><span class="s">d</span><span class="s">"</span> <span class="i" onmouseover="showTip(event, 'fstips22', 36)" onmouseout="hideTip(event, 'fstips22', 36)">person</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips9', 37)" onmouseout="hideTip(event, 'fstips9', 37)">Name</span> <span class="i" onmouseover="showTip(event, 'fstips22', 38)" onmouseout="hideTip(event, 'fstips22', 38)">person</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fstips11', 39)" onmouseout="hideTip(event, 'fstips11', 39)">Phone</span><br /><a class="fssniplink" href="http://tomasp.net/fswebsnippets" target="_blank">F# Web Snippets</a>
</pre>
<!-- HTML code for ToolTips -->
<div id="fstips1" class="tip">namespace System</div>
<div id="fstips2" class="tip">namespace System.IO</div>
<div id="fstips3" class="tip">namespace System.Runtime</div>
<div id="fstips4" class="tip">namespace System.Runtime.Serialization</div>
<div id="fstips5" class="tip">namespace System.Text</div>
<div id="fstips6" class="tip">type DataContractAttribute =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;inherit System.Attribute<br />&nbsp;&nbsp;&nbsp;&nbsp;new : unit -&gt; System.Runtime.Serialization.DataContractAttribute<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsReference : bool with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member Name : string with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member Namespace : string with get, set<br />&nbsp;&nbsp;end<br /><br />Full name: System.Runtime.Serialization.DataContractAttribute<br /><br />&nbsp;&nbsp;type: DataContractAttribute<br />&nbsp;&nbsp;implements: Runtime.InteropServices._Attribute<br />&nbsp;&nbsp;inherits: Attribute</div>
<div id="fstips7" class="tip">type Person =<br />&nbsp;&nbsp;{Name: string;<br />&nbsp;&nbsp;&nbsp;Phone: int;}<br /><br />Full name: Untitled.Person<br /><br />&nbsp;&nbsp;type: Person<br />&nbsp;&nbsp;implements: IEquatable&lt;Person&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;Person&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fstips8" class="tip">type DataMemberAttribute =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;inherit System.Attribute<br />&nbsp;&nbsp;&nbsp;&nbsp;new : unit -&gt; System.Runtime.Serialization.DataMemberAttribute<br />&nbsp;&nbsp;&nbsp;&nbsp;member EmitDefaultValue : bool with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsRequired : bool with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member Name : string with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member Order : int with get, set<br />&nbsp;&nbsp;end<br /><br />Full name: System.Runtime.Serialization.DataMemberAttribute<br /><br />&nbsp;&nbsp;type: DataMemberAttribute<br />&nbsp;&nbsp;implements: Runtime.InteropServices._Attribute<br />&nbsp;&nbsp;inherits: Attribute</div>
<div id="fstips9" class="tip">Person.Name: string</div>
<div id="fstips10" class="tip">Multiple items <br />val string : 'T -&gt; string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string <br /><br />--------------------<br /> <br />type string = String<br /><br />Full name: Microsoft.FSharp.Core.string<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fstips11" class="tip">Person.Phone: int</div>
<div id="fstips12" class="tip">Multiple items <br />val int : 'T -&gt; int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int <br /><br />--------------------<br /> <br />type int&lt;'Measure&gt; = int<br /><br />Full name: Microsoft.FSharp.Core.int&lt;_&gt;<br /><br />&nbsp;&nbsp;type: int&lt;'Measure&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IComparable&lt;int&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;inherits: ValueType<br /> <br /><br />--------------------<br /> <br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fstips13" class="tip">val jsonString : string<br /><br />Full name: Untitled.jsonString<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fstips14" class="tip">val js : Json.DataContractJsonSerializer<br /><br />Full name: Untitled.js<br /><br />&nbsp;&nbsp;type: Json.DataContractJsonSerializer<br />&nbsp;&nbsp;inherits: XmlObjectSerializer</div>
<div id="fstips15" class="tip">namespace System.Runtime.Serialization.Json</div>
<div id="fstips16" class="tip">type DataContractJsonSerializer =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;inherit System.Runtime.Serialization.XmlObjectSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * string -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * System.Xml.XmlDictionaryString -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * System.Collections.Generic.IEnumerable&lt;System.Type&gt; -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * string * System.Collections.Generic.IEnumerable&lt;System.Type&gt; -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * System.Xml.XmlDictionaryString * System.Collections.Generic.IEnumerable&lt;System.Type&gt; -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * System.Collections.Generic.IEnumerable&lt;System.Type&gt; * int * bool * System.Runtime.Serialization.IDataContractSurrogate * bool -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * string * System.Collections.Generic.IEnumerable&lt;System.Type&gt; * int * bool * System.Runtime.Serialization.IDataContractSurrogate * bool -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Type * System.Xml.XmlDictionaryString * System.Collections.Generic.IEnumerable&lt;System.Type&gt; * int * bool * System.Runtime.Serialization.IDataContractSurrogate * bool -&gt; System.Runtime.Serialization.Json.DataContractJsonSerializer<br />&nbsp;&nbsp;&nbsp;&nbsp;member DataContractSurrogate : System.Runtime.Serialization.IDataContractSurrogate<br />&nbsp;&nbsp;&nbsp;&nbsp;member IgnoreExtensionDataObject : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsStartObject : System.Xml.XmlReader -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsStartObject : System.Xml.XmlDictionaryReader -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member KnownTypes : System.Collections.ObjectModel.ReadOnlyCollection&lt;System.Type&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member MaxItemsInObjectGraph : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReadObject : System.IO.Stream -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReadObject : System.Xml.XmlReader -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReadObject : System.Xml.XmlDictionaryReader -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReadObject : System.Xml.XmlReader * bool -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReadObject : System.Xml.XmlDictionaryReader * bool -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteEndObject : System.Xml.XmlWriter -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteEndObject : System.Xml.XmlDictionaryWriter -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteObject : System.IO.Stream * obj -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteObject : System.Xml.XmlWriter * obj -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteObject : System.Xml.XmlDictionaryWriter * obj -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteObjectContent : System.Xml.XmlWriter * obj -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteObjectContent : System.Xml.XmlDictionaryWriter * obj -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteStartObject : System.Xml.XmlWriter * obj -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteStartObject : System.Xml.XmlDictionaryWriter * obj -&gt; unit<br />&nbsp;&nbsp;end<br /><br />Full name: System.Runtime.Serialization.Json.DataContractJsonSerializer<br /><br />&nbsp;&nbsp;type: Json.DataContractJsonSerializer<br />&nbsp;&nbsp;inherits: XmlObjectSerializer</div>
<div id="fstips17" class="tip">val typeof&lt;'T&gt; : Type<br /><br />Full name: Microsoft.FSharp.Core.Operators.typeof</div>
<div id="fstips18" class="tip">val buffer : byte []<br /><br />Full name: Untitled.buffer<br /><br />&nbsp;&nbsp;type: byte []<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: Collections.IList<br />&nbsp;&nbsp;implements: Collections.ICollection<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: Collections.Generic.IList&lt;byte&gt;<br />&nbsp;&nbsp;implements: Collections.Generic.ICollection&lt;byte&gt;<br />&nbsp;&nbsp;implements: seq&lt;byte&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;inherits: Array</div>
<div id="fstips19" class="tip">type Encoding =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;member BodyName : string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CodePage : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member DecoderFallback : System.Text.DecoderFallback with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member EncoderFallback : System.Text.EncoderFallback with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member EncodingName : string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetByteCount : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetByteCount : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetByteCount : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetByteCount : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBytes : char [] -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBytes : string -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBytes : char [] * int * int -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBytes : char * int * System.Byte * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBytes : char [] * int * int * System.Byte [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBytes : string * int * int * System.Byte [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetCharCount : System.Byte [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetCharCount : System.Byte * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetCharCount : System.Byte [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetChars : System.Byte [] -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetChars : System.Byte [] * int * int -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetChars : System.Byte * int * char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetChars : System.Byte [] * int * int * char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetDecoder : unit -&gt; System.Text.Decoder<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEncoder : unit -&gt; System.Text.Encoder<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetMaxByteCount : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetMaxCharCount : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetPreamble : unit -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetString : System.Byte [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetString : System.Byte [] * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member HeaderName : string<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsAlwaysNormalized : unit -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsAlwaysNormalized : System.Text.NormalizationForm -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsBrowserDisplay : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsBrowserSave : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsMailNewsDisplay : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsMailNewsSave : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsReadOnly : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSingleByte : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member WebName : string<br />&nbsp;&nbsp;&nbsp;&nbsp;member WindowsCodePage : int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ASCII : System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BigEndianUnicode : System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Convert : System.Text.Encoding * System.Text.Encoding * System.Byte [] -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Convert : System.Text.Encoding * System.Text.Encoding * System.Byte [] * int * int -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Default : System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetEncoding : int -&gt; System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetEncoding : string -&gt; System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetEncoding : int * System.Text.EncoderFallback * System.Text.DecoderFallback -&gt; System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetEncoding : string * System.Text.EncoderFallback * System.Text.DecoderFallback -&gt; System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetEncodings : unit -&gt; System.Text.EncodingInfo []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member UTF32 : System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member UTF7 : System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member UTF8 : System.Text.Encoding<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Unicode : System.Text.Encoding<br />&nbsp;&nbsp;end<br /><br />Full name: System.Text.Encoding<br /><br />&nbsp;&nbsp;type: Encoding<br />&nbsp;&nbsp;implements: ICloneable</div>
<div id="fstips20" class="tip">property Encoding.UTF8: Encoding</div>
<div id="fstips21" class="tip">Multiple overloads <br />Encoding.GetBytes(s: string) : byte [] <br />Encoding.GetBytes(chars: char []) : byte [] <br />Encoding.GetBytes(chars: char [], index: int, count: int) : byte [] <br />Encoding.GetBytes(chars: nativeptr&lt;char&gt;, charCount: int, bytes: nativeptr&lt;byte&gt;, byteCount: int) : int <br />Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int <br />Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int</div>
<div id="fstips22" class="tip">val person : Person<br /><br />Full name: Untitled.person<br /><br />&nbsp;&nbsp;type: Person<br />&nbsp;&nbsp;implements: IEquatable&lt;Person&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;Person&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fstips23" class="tip">Multiple overloads <br />XmlObjectSerializer.ReadObject(reader: Xml.XmlDictionaryReader) : obj <br />XmlObjectSerializer.ReadObject(reader: Xml.XmlReader) : obj <br />XmlObjectSerializer.ReadObject(stream: Stream) : obj <br />XmlObjectSerializer.ReadObject(reader: Xml.XmlDictionaryReader, verifyObjectName: bool) : obj <br />XmlObjectSerializer.ReadObject(reader: Xml.XmlReader, verifyObjectName: bool) : obj</div>
<div id="fstips24" class="tip">type MemoryStream =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;inherit System.IO.Stream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : unit -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : int -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Byte [] -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Byte [] * bool -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Byte [] * int * int -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Byte [] * int * int * bool -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.Byte [] * int * int * bool * bool -&gt; System.IO.MemoryStream<br />&nbsp;&nbsp;&nbsp;&nbsp;member CanRead : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member CanSeek : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member CanWrite : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Capacity : int with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member Flush : unit -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetBuffer : unit -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member Position : int64 with get, set<br />&nbsp;&nbsp;&nbsp;&nbsp;member Read : System.Byte [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member ReadByte : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Seek : int64 * System.IO.SeekOrigin -&gt; int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetLength : int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToArray : unit -&gt; System.Byte []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Write : System.Byte [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteByte : System.Byte -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member WriteTo : System.IO.Stream -&gt; unit<br />&nbsp;&nbsp;end<br /><br />Full name: System.IO.MemoryStream<br /><br />&nbsp;&nbsp;type: MemoryStream<br />&nbsp;&nbsp;implements: IDisposable<br />&nbsp;&nbsp;inherits: Stream<br />&nbsp;&nbsp;inherits: MarshalByRefObject</div>
<div id="fstips25" class="tip">val printfn : Printf.TextWriterFormat&lt;'T&gt; -&gt; 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
</div>
<p>&nbsp;</p>
<p>Quite simple, right? And you will have to agree with me that it is a little bit boring too&hellip;</p>
<h3>Fun with monadic parsers</h3>
<p>What is the fun option then? The fun way of parsing&nbsp;some JSON data (or any data format in fact) involves building your own parser from scratch! Better yet, building it from scratch by using Monadic Parsers! Believe me, it is a lot of fun: by the time I was done writing my parser, I had completely forgotten the reason I needed it in the first place.</p>
<p>The process is quite &ldquo;easy&rdquo;: (1) learn all about monads; (2) learn yourself some Haskell so you can understand the next step; (3) read Graham Hutton/Erik Meijer paper <a title="http://www.cs.nott.ac.uk/~gmh/pearl.pdf" href="http://www.cs.nott.ac.uk/~gmh/pearl.pdf" target="_blank">Monadic Parsing in Haskell</a>; (4) port the Haskell code to F#; (5) compose the JSON parser using the parser combinators; (6) figure out a way to go from the JSON abstract syntax tree to a F# record, and finally (7) use your JSON data!</p>
<p>Step (1) may take from a few minutes to a few years, depending on how deep you want to dive into it;&nbsp;I am not even going to try to cover it here. Interestingly enough, it seems that everybody is talking about Monads these days and there is a bunch of good tutorials and papers out there &ndash; read them all. Monads are called Computation Expressions in F#, and for the purposes of this blog series, this <a title="http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions" href="http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions" target="_blank">WikiBooks entry</a> should get you started on the main concepts: sequencing of computation/function composition and the syntactic sugar the F# compiler provides us to make life easier.</p>
<p>You should not, but if you prefer, you can actually skip steps (2), (3) and (4), and instead <a title="http://www.bing.com/search?q=monadic+parsing+in+f%23" href="http://www.bing.com/search?q=monadic+parsing+in+f%23" target="_blank">look around</a> for code samples to get you up and running quickly. We will go through similar code on this and next posts, so stick around if you feel like it... However, before we get to the parser monads, let&rsquo;s wobble through some code to get a glimpse of how they work under the covers.</p>
<p><em><span style="text-decoration: underline;">Disclaimer</span>: the parser we will build here is for education purposes only. If you plan on using monadic parsers in the wild, make sure to use a real one like <a title="http://www.quanttec.com/fparsec/" href="http://www.quanttec.com/fparsec/" target="_blank">FParsec</a>, which is the F# port of Haskell's Parsec&nbsp;library</em>.</p>
<h3>A simple hardcoded parser</h3>
<p>The best Parser Monad definition I&rsquo;ve found so far comes from <a title="Dr. Seuss" href="http://www.willamette.edu/~fruehr/haskell/seuss.html" target="_blank">Dr. Seuss</a> (who would think he was a functional developer!):</p>
<p style="padding-left: 30px;"><em>A Parser for Things</em><br /><em>is a function from Strings</em><br /><em>to Lists of Pairs</em><br /><em>of Things and Strings!</em></p>
<p>We could rewrite Dr. Seuss definition as:</p>
<p style="padding-left: 30px;"><em>A <span style="background-color: #ffff00;">Thing</span> Parser is a function that takes a <span style="background-color: #00ff00;">String</span> as a parameter, and returns a <span style="background-color: #ff9900;">list</span> of <span style="background-color: #00ffff;">Tuples of Things and Strings</span>.</em></p>
<p>It turns out that Dr. Seuss uses Haskell for his functional programming, and&nbsp;a Haskell <em>String</em> is just a type synonym for a list of characters. We could use&nbsp;<em>System.String</em> in our parsers, but to stick to Erik&rsquo;s paper convention, let&rsquo;s <span style="background-color: #ffffff;">use</span> F# char lists instead. The &ldquo;Thing&rdquo; in the definition above is just the type variable for the parser&hellip; using the F# type system notation, the definition above becomes:</p>
<p style="padding-left: 30px;"><em><span style="background-color: #ffff00;">&lsquo;a</span> Parser : <span style="background-color: #00ff00;">char list</span> -&gt; <span style="background-color: #00ffff;">(&lsquo;a * char list)</span> <span style="background-color: #ff9900;">list</span></em></p>
<p>We will be converting strings to list of chars and vice-versa a lot, so let&rsquo;s create a couple of simple helper functions:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun2', 2)" onmouseout="hideTip(event, 'fun2', 2)">s2cs</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun3', 3)" onmouseout="hideTip(event, 'fun3', 3)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun4', 4)" onmouseout="hideTip(event, 'fun4', 4)">ofSeq</span>
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun5', 5)" onmouseout="hideTip(event, 'fun5', 5)">cs2s</span> <span class="i" onmouseover="showTip(event, 'fun6', 6)" onmouseout="hideTip(event, 'fun6', 6)">cs</span> <span class="o">=</span> <span class="k">new</span> <span class="i" onmouseover="showTip(event, 'fun1', 7)" onmouseout="hideTip(event, 'fun1', 7)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun7', 8)" onmouseout="hideTip(event, 'fun7', 8)">String</span>(<span class="i" onmouseover="showTip(event, 'fun8', 9)" onmouseout="hideTip(event, 'fun8', 9)">Array</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun9', 10)" onmouseout="hideTip(event, 'fun9', 10)">ofList</span> <span class="i" onmouseover="showTip(event, 'fun6', 11)" onmouseout="hideTip(event, 'fun6', 11)">cs</span>)
</pre>
</div>
<p>Pretend we have this programming language that accepts only one line of code: <em>fun &lt;char&gt; = &lt;single digit integer&gt;.</em> One can&rsquo;t really do much programming with it, but it will be useful for our parser investigation. We can define its simple abstract syntax tree (AST) as:</p>
<div class="snippet">
<pre class="fssnip"><span class="c">//</span><span class="c"> </span><span class="c">fun</span><span class="c"> </span><span class="c">x</span><span class="c"> </span><span class="c">=</span><span class="c"> </span><span class="c">1</span>
<span class="k">type</span> <span class="i" onmouseover="showTip(event, 'fun10', 12)" onmouseout="hideTip(event, 'fun10', 12)">FunAST</span> <span class="o">=</span> 
    | <span class="i" onmouseover="showTip(event, 'fun11', 13)" onmouseout="hideTip(event, 'fun11', 13)">Fun</span> <span class="k">of</span> (<span class="i" onmouseover="showTip(event, 'fun12', 14)" onmouseout="hideTip(event, 'fun12', 14)">char</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun13', 15)" onmouseout="hideTip(event, 'fun13', 15)">int</span>)
</pre>
</div>
<p>&nbsp;</p>
<p>Our task will be, for example, to parse &ldquo;fun x = 1&rdquo; and emit Fun(&lsquo;x&rsquo;, 1).</p>
<p>Let&rsquo;s start by building the simplest parser we can think of, a character parser: given a list of characters (a string), it must return a list containing a tuple with the first character and the remaining ones; it does not get more &ldquo;building a parser from scratch&rdquo; than this:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun14', 16)" onmouseout="hideTip(event, 'fun14', 16)">charParser</span> (<span class="i" onmouseover="showTip(event, 'fun15', 17)" onmouseout="hideTip(event, 'fun15', 17)">chars</span> <span class="o">:</span> <span class="i" onmouseover="showTip(event, 'fun12', 18)" onmouseout="hideTip(event, 'fun12', 18)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 19)" onmouseout="hideTip(event, 'fun16', 19)">list</span>) <span class="o">=</span> 
    <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun15', 20)" onmouseout="hideTip(event, 'fun15', 20)">chars</span> <span class="k">with</span>
    | <span class="i" onmouseover="showTip(event, 'fun17', 21)" onmouseout="hideTip(event, 'fun17', 21)">c</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun6', 22)" onmouseout="hideTip(event, 'fun6', 22)">cs</span> <span class="k">-&gt;</span> [(<span class="i" onmouseover="showTip(event, 'fun17', 23)" onmouseout="hideTip(event, 'fun17', 23)">c</span>, <span class="i" onmouseover="showTip(event, 'fun6', 24)" onmouseout="hideTip(event, 'fun6', 24)">cs</span>)]
    | [] <span class="k">-&gt;</span> []</pre>
</div>
<p>&nbsp;</p>
<p>F# being such a great language for writing clean/succinct code, and because functional developers love to write clean/succinct code, we can rewrite the function above simply as:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun18', 25)" onmouseout="hideTip(event, 'fun18', 25)">cParser</span> <span class="o">=</span> <span class="k">function</span> [] <span class="k">-&gt;</span> [] | <span class="i" onmouseover="showTip(event, 'fun19', 26)" onmouseout="hideTip(event, 'fun19', 26)">c</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun20', 27)" onmouseout="hideTip(event, 'fun20', 27)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun19', 28)" onmouseout="hideTip(event, 'fun19', 28)">c</span>, <span class="i" onmouseover="showTip(event, 'fun20', 29)" onmouseout="hideTip(event, 'fun20', 29)">cs</span>]</pre>
</div>
<p>&nbsp;</p>
<p>Hover your mouse over the function declaration and you will see that it complies with Dr. Seuss definition: <em>val cParser: &lsquo;a list -&gt; (&lsquo;a * &lsquo;a list) list</em>! So here we go, our very first parser! Running it on F# Interactive gives us:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier; font-size: small;">&gt; "Test" |&gt; s2cs |&gt; cParser;;</span><br /><span style="font-family: courier new,courier; font-size: small;">val it : (char * char list) list = <span style="background-color: #ffff00;">[('T', <span style="background-color: #ff9900;">['e'; 's'; 't']</span>)]</span></span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier; font-size: small;">&gt; "T" |&gt; s2cs |&gt; cParser;;</span><br /><span style="font-family: courier new,courier; font-size: small;">val it : (char * char list) list = <span style="background-color: #ffff00;">[('T', <span style="background-color: #00ff00;">[]</span>)]</span></span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier; font-size: small;">&gt; "" |&gt; s2cs |&gt; cParser;;</span><br /><span style="font-family: courier new,courier; font-size: small;">val it : (char * char list) list = <span style="background-color: #ffff00;">[]</span></span></p>
<p>Note that, no matter which string you feed this parser, it will return a tuple with the first character and the list of remaining ones, all that inside another list; except, of course, if you feed it the empty string, in which case it returns an empty list. It is important to notice the usage of an empty list here, as it represents an error, or the &ldquo;end of the parsing computation&rdquo; because the parser failed to parse the input string.</p>
<p>Think of this<span style="background-color: #ffff00;"> result list</span> as a &ldquo;container&rdquo;: if it is empty, we are done parsing due to an error; if the result list if not empty, and the <span style="background-color: #00ff00;">second element of the tuple</span> is empty, we have successfully parsed the input string. If the <span style="background-color: #ff9900;">list inside the tuple is not empty</span>, we have successfully parsed part of the input string, but we still have more text to parse.</p>
<p>By the way, we can use <em>List.head</em> to extract the content of our result list:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "Test" |&gt; s2cs |&gt; cParser |&gt; List.head;;</span><br /><span style="font-family: courier new,courier;">val it : char * char list = ('T', ['e'; 's'; 't'])</span></p>
<p>Back to our one-line programming language, how would we go about parsing &ldquo;fun x = 1&rdquo; using our <em>char</em> Parser above? If all our parser provides is a <em>char</em> at a time, we will need to parse a <em>char</em>, test it with the language specification, parse another one, test it, etc., etc., something like this:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun21', 30)" onmouseout="hideTip(event, 'fun21', 30)">uglyParser</span> <span class="i" onmouseover="showTip(event, 'fun6', 31)" onmouseout="hideTip(event, 'fun6', 31)">cs</span> <span class="o">=</span> 
    <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun22', 32)" onmouseout="hideTip(event, 'fun22', 32)">c1</span>, <span class="i" onmouseover="showTip(event, 'fun23', 33)" onmouseout="hideTip(event, 'fun23', 33)">cs1</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 34)" onmouseout="hideTip(event, 'fun18', 34)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun6', 35)" onmouseout="hideTip(event, 'fun6', 35)">cs</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 36)" onmouseout="hideTip(event, 'fun3', 36)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 37)" onmouseout="hideTip(event, 'fun24', 37)">head</span>
    <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun22', 38)" onmouseout="hideTip(event, 'fun22', 38)">c1</span> <span class="o">=</span> <span class="s">'f'</span> <span class="k">then</span>
        <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun25', 39)" onmouseout="hideTip(event, 'fun25', 39)">c2</span>, <span class="i" onmouseover="showTip(event, 'fun26', 40)" onmouseout="hideTip(event, 'fun26', 40)">cs2</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 41)" onmouseout="hideTip(event, 'fun18', 41)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun23', 42)" onmouseout="hideTip(event, 'fun23', 42)">cs1</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 43)" onmouseout="hideTip(event, 'fun3', 43)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 44)" onmouseout="hideTip(event, 'fun24', 44)">head</span>
        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun25', 45)" onmouseout="hideTip(event, 'fun25', 45)">c2</span> <span class="o">=</span> <span class="s">'u'</span> <span class="k">then</span>
            <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun27', 46)" onmouseout="hideTip(event, 'fun27', 46)">c3</span>, <span class="i" onmouseover="showTip(event, 'fun28', 47)" onmouseout="hideTip(event, 'fun28', 47)">cs3</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 48)" onmouseout="hideTip(event, 'fun18', 48)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun26', 49)" onmouseout="hideTip(event, 'fun26', 49)">cs2</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 50)" onmouseout="hideTip(event, 'fun3', 50)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 51)" onmouseout="hideTip(event, 'fun24', 51)">head</span>
            <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun27', 52)" onmouseout="hideTip(event, 'fun27', 52)">c3</span> <span class="o">=</span> <span class="s">'n'</span> <span class="k">then</span> 
                <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun29', 53)" onmouseout="hideTip(event, 'fun29', 53)">c4</span>, <span class="i" onmouseover="showTip(event, 'fun30', 54)" onmouseout="hideTip(event, 'fun30', 54)">cs4</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 55)" onmouseout="hideTip(event, 'fun18', 55)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun28', 56)" onmouseout="hideTip(event, 'fun28', 56)">cs3</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 57)" onmouseout="hideTip(event, 'fun3', 57)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 58)" onmouseout="hideTip(event, 'fun24', 58)">head</span>
                <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun29', 59)" onmouseout="hideTip(event, 'fun29', 59)">c4</span> <span class="o">=</span> <span class="s">' '</span> <span class="k">then</span>
                    <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun31', 60)" onmouseout="hideTip(event, 'fun31', 60)">c5</span>, <span class="i" onmouseover="showTip(event, 'fun32', 61)" onmouseout="hideTip(event, 'fun32', 61)">cs5</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 62)" onmouseout="hideTip(event, 'fun18', 62)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun30', 63)" onmouseout="hideTip(event, 'fun30', 63)">cs4</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 64)" onmouseout="hideTip(event, 'fun3', 64)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 65)" onmouseout="hideTip(event, 'fun24', 65)">head</span>
                    <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun31', 66)" onmouseout="hideTip(event, 'fun31', 66)">c5</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun31', 67)" onmouseout="hideTip(event, 'fun31', 67)">c5</span> <span class="k">then</span>
                        <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun33', 68)" onmouseout="hideTip(event, 'fun33', 68)">c6</span>, <span class="i" onmouseover="showTip(event, 'fun34', 69)" onmouseout="hideTip(event, 'fun34', 69)">cs6</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 70)" onmouseout="hideTip(event, 'fun18', 70)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun32', 71)" onmouseout="hideTip(event, 'fun32', 71)">cs5</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 72)" onmouseout="hideTip(event, 'fun3', 72)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 73)" onmouseout="hideTip(event, 'fun24', 73)">head</span>
                        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun33', 74)" onmouseout="hideTip(event, 'fun33', 74)">c6</span> <span class="o">=</span> <span class="s">' '</span> <span class="k">then</span>
                            <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun35', 75)" onmouseout="hideTip(event, 'fun35', 75)">c7</span>, <span class="i" onmouseover="showTip(event, 'fun36', 76)" onmouseout="hideTip(event, 'fun36', 76)">cs7</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 77)" onmouseout="hideTip(event, 'fun18', 77)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun34', 78)" onmouseout="hideTip(event, 'fun34', 78)">cs6</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 79)" onmouseout="hideTip(event, 'fun3', 79)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 80)" onmouseout="hideTip(event, 'fun24', 80)">head</span>
                            <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun35', 81)" onmouseout="hideTip(event, 'fun35', 81)">c7</span> <span class="o">=</span> <span class="s">'='</span> <span class="k">then</span>
                                <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun37', 82)" onmouseout="hideTip(event, 'fun37', 82)">c8</span>, <span class="i" onmouseover="showTip(event, 'fun38', 83)" onmouseout="hideTip(event, 'fun38', 83)">cs8</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 84)" onmouseout="hideTip(event, 'fun18', 84)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun36', 85)" onmouseout="hideTip(event, 'fun36', 85)">cs7</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 86)" onmouseout="hideTip(event, 'fun3', 86)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 87)" onmouseout="hideTip(event, 'fun24', 87)">head</span>
                                <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun37', 88)" onmouseout="hideTip(event, 'fun37', 88)">c8</span> <span class="o">=</span> <span class="s">' '</span> <span class="k">then</span> 
                                    <span class="k">let</span> (<span class="i" onmouseover="showTip(event, 'fun39', 89)" onmouseout="hideTip(event, 'fun39', 89)">c9</span>, <span class="i" onmouseover="showTip(event, 'fun40', 90)" onmouseout="hideTip(event, 'fun40', 90)">cs9</span>) <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun18', 91)" onmouseout="hideTip(event, 'fun18', 91)">cParser</span> <span class="i" onmouseover="showTip(event, 'fun38', 92)" onmouseout="hideTip(event, 'fun38', 92)">cs8</span> <span class="o">|&gt;</span> <span class="i" onmouseover="showTip(event, 'fun3', 93)" onmouseout="hideTip(event, 'fun3', 93)">List</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun24', 94)" onmouseout="hideTip(event, 'fun24', 94)">head</span>
                                    <span class="k">if</span>  <span class="i" onmouseover="showTip(event, 'fun41', 95)" onmouseout="hideTip(event, 'fun41', 95)">Char</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun42', 96)" onmouseout="hideTip(event, 'fun42', 96)">IsDigit</span> <span class="i" onmouseover="showTip(event, 'fun39', 97)" onmouseout="hideTip(event, 'fun39', 97)">c9</span> <span class="k">then</span>
                                        <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun43', 98)" onmouseout="hideTip(event, 'fun43', 98)">num</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun1', 99)" onmouseout="hideTip(event, 'fun1', 99)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun44', 100)" onmouseout="hideTip(event, 'fun44', 100)">Int32</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun45', 101)" onmouseout="hideTip(event, 'fun45', 101)">Parse</span>(<span class="i" onmouseover="showTip(event, 'fun46', 102)" onmouseout="hideTip(event, 'fun46', 102)">string</span> <span class="i" onmouseover="showTip(event, 'fun39', 103)" onmouseout="hideTip(event, 'fun39', 103)">c9</span>)
                                        [<span class="i" onmouseover="showTip(event, 'fun11', 104)" onmouseout="hideTip(event, 'fun11', 104)">Fun</span> (<span class="i" onmouseover="showTip(event, 'fun31', 105)" onmouseout="hideTip(event, 'fun31', 105)">c5</span>, <span class="i" onmouseover="showTip(event, 'fun43', 106)" onmouseout="hideTip(event, 'fun43', 106)">num</span>), <span class="i" onmouseover="showTip(event, 'fun40', 107)" onmouseout="hideTip(event, 'fun40', 107)">cs9</span>]
                                    <span class="k">else</span> []
                                <span class="k">else</span> []
                            <span class="k">else</span> []
                        <span class="k">else</span> []
                    <span class="k">else</span> []
                <span class="k">else</span> []
            <span class="k">else</span> []
        <span class="k">else</span> []
    <span class="k">else</span> []
</pre>
</div>
<p>&nbsp;</p>
<p>If you hover your mouse over uglyParser, you will notice that it does comply with our parser definition, and if you run it on F# Interactive you will see that it actually works just fine&hellip; however it is as ugly as ugly can be!</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x = 1" |&gt; s2cs |&gt; uglyParser;;</span><br /><span style="font-family: courier new,courier;">val it : (FunAST * char list) list = [(<strong>Fun ('x', 1)</strong>, [])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fail x = 1" |&gt; s2cs |&gt; uglyParser;;val it : (FunAST * char list) list = []</span></p>
<p>It is obvious we are repeating code again and again; we apply the <em>char</em> parser, run a function on the result (<em>if c1 = &lsquo;f&rsquo; then&hellip;</em>) and return a new parser, we apply that new parser, run another function on the result and return yet another new parser, and so one. We are basically &ldquo;sequencing&rdquo; parsers manually; it would be great if we could write something like this instead:</p>
<p><span style="font-family: courier new,courier;">continuationFunction(aResult) = process(aResult) and return(bParser)</span></p>
<p><span style="font-family: courier new,courier;">sequenceFunction(aParser, <span style="font-family: courier new,courier;">continuationFunction</span>) = </span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">let (aResult, remaining) = sequence(aParser)</span><br /><span style="font-family: courier new,courier;">let bParser = continuationFunction aResult</span><br /><span style="font-family: courier new,courier;">bParser (remaining</span>)</p>
<p>Analyzing the code pseudo-code above,&nbsp;we can try to infer the types of those two functions, remembering our parser type definition:</p>
<p><span style="font-family: courier new,courier;">&lsquo;a Parser: char list -&gt; (&lsquo;a * char list) list</span></p>
<p><span style="font-family: courier new,courier;"></span>the types of our functions above become:</p>
<p><span style="font-family: courier new,courier;">continuationFunction: &lsquo;a -&gt; <span style="background-color: #ffff00;">&lsquo;b Parser</span></span><br /><span style="font-family: courier new,courier;">continuationFunction: &lsquo;a -&gt; <span style="background-color: #ffff00;">(char list -&gt; &lsquo;b * char list) list</span></span></p>
<p><span style="font-family: courier new,courier;">sequenceFunction: <span style="background-color: #ffcc00;">&lsquo;a Parser</span> * (&lsquo;a -&gt; <span style="background-color: #ffff00;">&lsquo;b Parser</span>) -&gt; <span style="background-color: #ffff00;">&lsquo;b Parser</span></span><br /><span style="font-family: courier new,courier;">sequenceFunction: (<span style="background-color: #ffcc00;"><span class="i" onmouseover="showTip(event, 'fun12', 110)" onmouseout="hideTip(event, 'fun12', 110)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 111)" onmouseout="hideTip(event, 'fun16', 111)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">a</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun12', 112)" onmouseout="hideTip(event, 'fun12', 112)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 113)" onmouseout="hideTip(event, 'fun16', 113)">list</span>) <span class="i" onmouseover="showTip(event, 'fun16', 114)" onmouseout="hideTip(event, 'fun16', 114)">list</span></span>) * (&lsquo;a -&gt; <span style="background-color: #ffff00;">(char list -&gt; &lsquo;b * char list) list</span>) -&gt; <span style="background-color: #ffff00;">(char list -&gt; &lsquo;b * char list) list</span></span></p>
<p>Our sequence function takes an <i>&lsquo;a Parser</i>, a function that knows how to go from <i>&lsquo;a</i> to a <i>&lsquo;b Parser</i> and returns a <i>&lsquo;b Parser</i>&hellip; Let&rsquo;s write some real F# code:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun47', 108)" onmouseout="hideTip(event, 'fun47', 108)">sequence</span> (<span class="i" onmouseover="showTip(event, 'fun48', 109)" onmouseout="hideTip(event, 'fun48', 109)">aParser</span><span class="o">:</span>(<span class="i" onmouseover="showTip(event, 'fun12', 110)" onmouseout="hideTip(event, 'fun12', 110)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 111)" onmouseout="hideTip(event, 'fun16', 111)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">a</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun12', 112)" onmouseout="hideTip(event, 'fun12', 112)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 113)" onmouseout="hideTip(event, 'fun16', 113)">list</span>) <span class="i" onmouseover="showTip(event, 'fun16', 114)" onmouseout="hideTip(event, 'fun16', 114)">list</span>), (<span class="i" onmouseover="showTip(event, 'fun49', 115)" onmouseout="hideTip(event, 'fun49', 115)">continutationFunc</span> <span class="o">:</span> <span class="o">'</span><span class="i">a</span> <span class="k">-&gt;</span> (<span class="i" onmouseover="showTip(event, 'fun12', 116)" onmouseout="hideTip(event, 'fun12', 116)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 117)" onmouseout="hideTip(event, 'fun16', 117)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">b</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun12', 118)" onmouseout="hideTip(event, 'fun12', 118)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 119)" onmouseout="hideTip(event, 'fun16', 119)">list</span>) <span class="i" onmouseover="showTip(event, 'fun16', 120)" onmouseout="hideTip(event, 'fun16', 120)">list</span>))) <span class="i" onmouseover="showTip(event, 'fun6', 121)" onmouseout="hideTip(event, 'fun6', 121)">cs</span> <span class="o">=</span> 
    <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun48', 122)" onmouseout="hideTip(event, 'fun48', 122)">aParser</span> <span class="i" onmouseover="showTip(event, 'fun6', 123)" onmouseout="hideTip(event, 'fun6', 123)">cs</span> <span class="k">with</span>
    | (<span class="i" onmouseover="showTip(event, 'fun50', 124)" onmouseout="hideTip(event, 'fun50', 124)">c'</span>, <span class="i" onmouseover="showTip(event, 'fun51', 125)" onmouseout="hideTip(event, 'fun51', 125)">cs'</span>)<span class="o">::</span>_ <span class="k">-&gt;</span> 
        <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun52', 126)" onmouseout="hideTip(event, 'fun52', 126)">bParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun49', 127)" onmouseout="hideTip(event, 'fun49', 127)">continutationFunc</span> <span class="i" onmouseover="showTip(event, 'fun50', 128)" onmouseout="hideTip(event, 'fun50', 128)">c'</span>
        <span class="i" onmouseover="showTip(event, 'fun52', 129)" onmouseout="hideTip(event, 'fun52', 129)">bParser</span> <span class="i" onmouseover="showTip(event, 'fun51', 130)" onmouseout="hideTip(event, 'fun51', 130)">cs'</span>
    | [] <span class="k">-&gt;</span> []
</pre>
</div>
<p>&nbsp;</p>
<p>What?! Yes, kind of crazy, we upped the game a little bit here and things got slightly more complex, but if you stare at it long enough it will eventually make sense (or give you some headache). The implementation is actually quite simple, we apply the <i>aParser</i> on the input char list (<em>cs</em>), if there is a parsing error, we return the empty list, otherwise we apply the <em>continuationFunc</em> on the thing parsed (<em>c&rsquo;</em>), which gives us the <em>bParser</em>, and finally we apply the <em>bParser</em> on the remaining char list (ohhh&hellip;.).</p>
<p>I know we are not using monads yet, but just to get us closer to that, I&rsquo;d like to rename and rewrite the sequence function above before using it. I will call it <em>bind</em> and use a different notation, by removing the <i>cs</i> from its declaration, to emphasize that <em>bind</em> returns a function (the behavior continues exactly the same):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun53', 131)" onmouseout="hideTip(event, 'fun53', 131)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun54', 132)" onmouseout="hideTip(event, 'fun54', 132)">p</span><span class="o">:</span>(<span class="i" onmouseover="showTip(event, 'fun12', 133)" onmouseout="hideTip(event, 'fun12', 133)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 134)" onmouseout="hideTip(event, 'fun16', 134)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">a</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun12', 135)" onmouseout="hideTip(event, 'fun12', 135)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 136)" onmouseout="hideTip(event, 'fun16', 136)">list</span>) <span class="i" onmouseover="showTip(event, 'fun16', 137)" onmouseout="hideTip(event, 'fun16', 137)">list</span>), (<span class="i" onmouseover="showTip(event, 'fun55', 138)" onmouseout="hideTip(event, 'fun55', 138)">f</span> <span class="o">:</span> <span class="o">'</span><span class="i">a</span> <span class="k">-&gt;</span> (<span class="i" onmouseover="showTip(event, 'fun12', 139)" onmouseout="hideTip(event, 'fun12', 139)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 140)" onmouseout="hideTip(event, 'fun16', 140)">list</span> <span class="k">-&gt;</span> (<span class="o">'</span><span class="i">b</span> <span class="o">*</span> <span class="i" onmouseover="showTip(event, 'fun12', 141)" onmouseout="hideTip(event, 'fun12', 141)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 142)" onmouseout="hideTip(event, 'fun16', 142)">list</span>) <span class="i" onmouseover="showTip(event, 'fun16', 143)" onmouseout="hideTip(event, 'fun16', 143)">list</span>))) <span class="o">=</span> 
    <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun6', 144)" onmouseout="hideTip(event, 'fun6', 144)">cs</span> <span class="k">-&gt;</span> 
        <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun54', 145)" onmouseout="hideTip(event, 'fun54', 145)">p</span> <span class="i" onmouseover="showTip(event, 'fun6', 146)" onmouseout="hideTip(event, 'fun6', 146)">cs</span> <span class="k">with</span>
        | (<span class="i" onmouseover="showTip(event, 'fun50', 147)" onmouseout="hideTip(event, 'fun50', 147)">c'</span>, <span class="i" onmouseover="showTip(event, 'fun51', 148)" onmouseout="hideTip(event, 'fun51', 148)">cs'</span>)<span class="o">::</span>_ <span class="k">-&gt;</span> (<span class="i" onmouseover="showTip(event, 'fun55', 149)" onmouseout="hideTip(event, 'fun55', 149)">f</span> <span class="i" onmouseover="showTip(event, 'fun50', 150)" onmouseout="hideTip(event, 'fun50', 150)">c'</span>) <span class="i" onmouseover="showTip(event, 'fun51', 151)" onmouseout="hideTip(event, 'fun51', 151)">cs'</span>
        | [] <span class="k">-&gt;</span> []
</pre>
</div>
<p>&nbsp;</p>
<p>With this new notation, it easier to see that <em>bind</em> is returning a parser, which is the expected behavior: if I sequence, or bind, two parsers, the result has to be another parser, right? With <em>bind</em> in place, let&rsquo;s write a parser that parses the token &ldquo;fun&rdquo; out of &ldquo;fun x = 1&rdquo; using it:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun56', 152)" onmouseout="hideTip(event, 'fun56', 152)">uglyFunParser</span> <span class="i" onmouseover="showTip(event, 'fun57', 153)" onmouseout="hideTip(event, 'fun57', 153)">input</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 154)" onmouseout="hideTip(event, 'fun53', 154)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun18', 155)" onmouseout="hideTip(event, 'fun18', 155)">cParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun22', 156)" onmouseout="hideTip(event, 'fun22', 156)">c1</span> <span class="k">-&gt;</span>
        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun22', 157)" onmouseout="hideTip(event, 'fun22', 157)">c1</span> <span class="o">=</span> <span class="s">'f'</span> <span class="k">then</span>
            <span class="i" onmouseover="showTip(event, 'fun53', 158)" onmouseout="hideTip(event, 'fun53', 158)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun18', 159)" onmouseout="hideTip(event, 'fun18', 159)">cParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun25', 160)" onmouseout="hideTip(event, 'fun25', 160)">c2</span> <span class="k">-&gt;</span>
                <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun25', 161)" onmouseout="hideTip(event, 'fun25', 161)">c2</span> <span class="o">=</span> <span class="s">'u'</span> <span class="k">then</span>
                    <span class="i" onmouseover="showTip(event, 'fun53', 162)" onmouseout="hideTip(event, 'fun53', 162)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun18', 163)" onmouseout="hideTip(event, 'fun18', 163)">cParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun27', 164)" onmouseout="hideTip(event, 'fun27', 164)">c3</span> <span class="k">-&gt;</span>
                        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun27', 165)" onmouseout="hideTip(event, 'fun27', 165)">c3</span> <span class="o">=</span> <span class="s">'n'</span> <span class="k">then</span>
                            <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun6', 166)" onmouseout="hideTip(event, 'fun6', 166)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun11', 167)" onmouseout="hideTip(event, 'fun11', 167)">Fun</span>, <span class="i" onmouseover="showTip(event, 'fun6', 168)" onmouseout="hideTip(event, 'fun6', 168)">cs</span>]
                        <span class="k">else</span> <span class="k">fun</span> _ <span class="k">-&gt;</span> []
                    )
                <span class="k">else</span> <span class="k">fun</span> _ <span class="k">-&gt;</span> []
            )
        <span class="k">else</span> <span class="k">fun</span> _ <span class="k">-&gt;</span> []
    ) <span class="i" onmouseover="showTip(event, 'fun57', 169)" onmouseout="hideTip(event, 'fun57', 169)">input</span>
</pre>
</div>
<p><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x = 1" |&gt; s2cs |&gt; uglyFunParser;;</span><br /><span style="font-family: courier new,courier;">val it : ((char * int -&gt; FunAST) * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [(&lt;fun:uglyFunParser@73-20&gt;, [' '; 'x'; ' '; '='; ' '; '1'])]</span></p>
<p>It works perfectly, but still quite ugly... However, we now have in place the basis of sequencing those parsing computations. It is very important that you understand what&rsquo;s going on here&hellip; we are using a lot of anonymous functions instead of explicitly declaring several <em>continuationFunc</em>s, and each of these anonymous functions binds, or sequences, another parser.</p>
<p>&ldquo;What&rsquo;s up with all those &ldquo;fun _ -&gt; []&rdquo; and &ldquo;fun cs -&gt; [Fun, cs]&rdquo;? Remember that any parser we build must comply with Dr. Seuss definition, they are functions that take a char list (<i>cs</i>) and return an empty list (error) or a list with the tuple (thing parsed * remaining char list); and that&rsquo;s exactly what we are doing, in case of error we return a function that takes one parameter (but we don't care about it, so we throw it away with the "_" notation), and returns the empty list (&ldquo;<em>fun _ -&gt; []</em>&rdquo;), and in case of success we return &ldquo;<em>fun cs -&gt; [(Fun, cs)]</em>&rdquo;, i.e., a function that takes a char list and returns the tuple (parsed thing (<em>Fun</em>), remaining chars).</p>
<p>These two anonymous functions are so important that we ought to build helper functions for them, let&rsquo;s call them &ldquo;returnParser&rdquo; for the success case, and &ldquo;zeroParser&rdquo; for the case of parsing errors:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun58', 170)" onmouseout="hideTip(event, 'fun58', 170)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun59', 171)" onmouseout="hideTip(event, 'fun59', 171)">something</span> <span class="o">=</span> <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun60', 172)" onmouseout="hideTip(event, 'fun60', 172)">cs</span> <span class="k">-&gt;</span> [<span class="i" onmouseover="showTip(event, 'fun59', 173)" onmouseout="hideTip(event, 'fun59', 173)">something</span>, <span class="i" onmouseover="showTip(event, 'fun60', 174)" onmouseout="hideTip(event, 'fun60', 174)">cs</span>]
<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun61', 175)" onmouseout="hideTip(event, 'fun61', 175)">zeroParser</span> () <span class="o">=</span> <span class="k">fun</span> _ <span class="k">-&gt;</span> []
</pre>
</div>
<p>&nbsp;</p>
<p>It is also time to get rid of the if-then-else madness of our ugly function! We will start by defining a &ldquo;satisfy this predicate Parser&rdquo;, the idea being, given a predicate function (&lsquo;a -&gt; bool), it returns a parser which can only parse things where the predicate returns true &ndash; it is almost a direct copy-and-paste of one section of the <em>funUglyParser</em> above:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun62', 176)" onmouseout="hideTip(event, 'fun62', 176)">satisfyParser</span> <span class="i" onmouseover="showTip(event, 'fun63', 177)" onmouseout="hideTip(event, 'fun63', 177)">pred</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 178)" onmouseout="hideTip(event, 'fun53', 178)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun18', 179)" onmouseout="hideTip(event, 'fun18', 179)">cParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun17', 180)" onmouseout="hideTip(event, 'fun17', 180)">c</span> <span class="k">-&gt;</span>
        <span class="k">if</span> <span class="i" onmouseover="showTip(event, 'fun63', 181)" onmouseout="hideTip(event, 'fun63', 181)">pred</span> <span class="i" onmouseover="showTip(event, 'fun17', 182)" onmouseout="hideTip(event, 'fun17', 182)">c</span> <span class="k">then</span> <span class="i" onmouseover="showTip(event, 'fun58', 183)" onmouseout="hideTip(event, 'fun58', 183)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun17', 184)" onmouseout="hideTip(event, 'fun17', 184)">c</span> <span class="k">else</span> <span class="i" onmouseover="showTip(event, 'fun61', 185)" onmouseout="hideTip(event, 'fun61', 185)">zeroParser</span>()
    )
    <span class="c">//</span><span class="c">let</span><span class="c"> </span><span class="c">(c',</span><span class="c"> </span><span class="c">cs')</span><span class="c"> </span><span class="c">=</span><span class="c"> </span><span class="c">cParser</span><span class="c"> </span><span class="c">cs</span><span class="c"> </span><span class="c">|&gt;</span><span class="c"> </span><span class="c">List.head</span>
    <span class="c">//</span><span class="c">if</span><span class="c"> </span><span class="c">pred</span><span class="c"> </span><span class="c">c'</span><span class="c"> </span><span class="c">then</span><span class="c"> </span><span class="c">[c',</span><span class="c"> </span><span class="c">cs']</span><span class="c"> </span><span class="c">else</span><span class="c"> </span><span class="c">[]</span>
</pre>
</div>
<p>&nbsp;</p>
<p>Make sure to hover your mouse over it and confirm its type complies with our parser definition. With this new parser in place, let&rsquo;s create an &ldquo;only parse this specific character Parser&rdquo;, and call it &ldquo;tcParser&rdquo; (as in "this char Parser"):</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun64', 186)" onmouseout="hideTip(event, 'fun64', 186)">tcParser</span> <span class="i" onmouseover="showTip(event, 'fun17', 187)" onmouseout="hideTip(event, 'fun17', 187)">c</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun62', 188)" onmouseout="hideTip(event, 'fun62', 188)">satisfyParser</span> ((<span class="o">=</span>) <span class="i" onmouseover="showTip(event, 'fun17', 189)" onmouseout="hideTip(event, 'fun17', 189)">c</span>)
</pre>
</div>
<p>&nbsp;</p>
<p>Kind of cool, no? Testing it:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x = 1" |&gt; s2cs |&gt; tcParser 'f';;</span><br /><span style="font-family: courier new,courier;">val it : (char * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [('f', ['u'; 'n'; ' '; 'x'; ' '; '='; ' '; '1'])]</span></p>
<p>And it works&hellip; how about sequencing this little guy to improve our funParser?</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun65', 190)" onmouseout="hideTip(event, 'fun65', 190)">funParser</span> (<span class="i" onmouseover="showTip(event, 'fun57', 191)" onmouseout="hideTip(event, 'fun57', 191)">input</span><span class="o">:</span> <span class="i" onmouseover="showTip(event, 'fun12', 192)" onmouseout="hideTip(event, 'fun12', 192)">char</span> <span class="i" onmouseover="showTip(event, 'fun16', 193)" onmouseout="hideTip(event, 'fun16', 193)">list</span>) <span class="o">=</span> 
    <span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun66', 194)" onmouseout="hideTip(event, 'fun66', 194)">internalParser</span> <span class="o">=</span> 
        <span class="i" onmouseover="showTip(event, 'fun53', 195)" onmouseout="hideTip(event, 'fun53', 195)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun64', 196)" onmouseout="hideTip(event, 'fun64', 196)">tcParser</span> <span class="s">'f'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
            <span class="i" onmouseover="showTip(event, 'fun53', 197)" onmouseout="hideTip(event, 'fun53', 197)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun64', 198)" onmouseout="hideTip(event, 'fun64', 198)">tcParser</span> <span class="s">'u'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
                <span class="i" onmouseover="showTip(event, 'fun53', 199)" onmouseout="hideTip(event, 'fun53', 199)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun64', 200)" onmouseout="hideTip(event, 'fun64', 200)">tcParser</span> <span class="s">'n'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
                    <span class="i" onmouseover="showTip(event, 'fun58', 201)" onmouseout="hideTip(event, 'fun58', 201)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun11', 202)" onmouseout="hideTip(event, 'fun11', 202)">Fun</span>
                )
            )
        )
    <span class="i" onmouseover="showTip(event, 'fun66', 203)" onmouseout="hideTip(event, 'fun66', 203)">internalParser</span> <span class="i" onmouseover="showTip(event, 'fun57', 204)" onmouseout="hideTip(event, 'fun57', 204)">input</span>
</pre>
</div>
<p>&nbsp;</p>
<p>The <em>input</em> parameter is really not helping much here, by this time we all know that parsers take char lists as input, so let&rsquo;s remove it:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun67', 205)" onmouseout="hideTip(event, 'fun67', 205)">funParser'</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 206)" onmouseout="hideTip(event, 'fun53', 206)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun64', 207)" onmouseout="hideTip(event, 'fun64', 207)">tcParser</span> <span class="s">'f'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
        <span class="i" onmouseover="showTip(event, 'fun53', 208)" onmouseout="hideTip(event, 'fun53', 208)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun64', 209)" onmouseout="hideTip(event, 'fun64', 209)">tcParser</span> <span class="s">'u'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
            <span class="i" onmouseover="showTip(event, 'fun53', 210)" onmouseout="hideTip(event, 'fun53', 210)">bind</span> (<span class="i" onmouseover="showTip(event, 'fun64', 211)" onmouseout="hideTip(event, 'fun64', 211)">tcParser</span> <span class="s">'n'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
                <span class="i" onmouseover="showTip(event, 'fun58', 212)" onmouseout="hideTip(event, 'fun58', 212)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun11', 213)" onmouseout="hideTip(event, 'fun11', 213)">Fun</span>
            )
        )
    )
</pre>
</div>
<p><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x = 1" |&gt; s2cs |&gt; funParser';;</span><br /><span style="font-family: courier new,courier;">val it : ((char * int -&gt; FunAST) * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [(&lt;fun:funParser'@100-3&gt;, [' '; 'x'; ' '; '='; ' '; '1'])]</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fail x = 1" |&gt; s2cs |&gt; funParser';;</span><br /><span style="font-family: courier new,courier;">val it : ((char * int -&gt; FunAST) * char list) list = []</span></p>
<p>You&nbsp;have to agree again that this is much cleaner than our very first uglyParser. We are not even using the zeroParser anymore, since satisfyParser takes care of that for us. But we are now facing another pattern, sequencing the application of the tcParsers. Can we do better than that? Sure thing&hellip; let&rsquo;s create a &ldquo;parse this specific string Parser&rdquo;:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun68', 214)" onmouseout="hideTip(event, 'fun68', 214)">stringParser</span> (<span class="i" onmouseover="showTip(event, 'fun69', 215)" onmouseout="hideTip(event, 'fun69', 215)">tok</span><span class="o">:</span><span class="i" onmouseover="showTip(event, 'fun46', 216)" onmouseout="hideTip(event, 'fun46', 216)">string</span>) <span class="o">=</span>
    <span class="k">let</span> <span class="k">rec</span> <span class="i" onmouseover="showTip(event, 'fun70', 217)" onmouseout="hideTip(event, 'fun70', 217)">text</span> <span class="o">=</span> <span class="k">function</span>
        | [] <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun58', 218)" onmouseout="hideTip(event, 'fun58', 218)">returnParser</span> []
        | <span class="i" onmouseover="showTip(event, 'fun71', 219)" onmouseout="hideTip(event, 'fun71', 219)">t</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun72', 220)" onmouseout="hideTip(event, 'fun72', 220)">tok'</span> <span class="k">-&gt;</span> 
            <span class="i" onmouseover="showTip(event, 'fun53', 221)" onmouseout="hideTip(event, 'fun53', 221)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun64', 222)" onmouseout="hideTip(event, 'fun64', 222)">tcParser</span> <span class="i" onmouseover="showTip(event, 'fun71', 223)" onmouseout="hideTip(event, 'fun71', 223)">t</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
                <span class="i" onmouseover="showTip(event, 'fun53', 224)" onmouseout="hideTip(event, 'fun53', 224)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun70', 225)" onmouseout="hideTip(event, 'fun70', 225)">text</span> <span class="i" onmouseover="showTip(event, 'fun72', 226)" onmouseout="hideTip(event, 'fun72', 226)">tok'</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun58', 227)" onmouseout="hideTip(event, 'fun58', 227)">returnParser</span> (<span class="i" onmouseover="showTip(event, 'fun71', 228)" onmouseout="hideTip(event, 'fun71', 228)">t</span><span class="o">::</span><span class="i" onmouseover="showTip(event, 'fun72', 229)" onmouseout="hideTip(event, 'fun72', 229)">tok'</span>) )
            )
    <span class="i" onmouseover="showTip(event, 'fun70', 230)" onmouseout="hideTip(event, 'fun70', 230)">text</span> (<span class="i" onmouseover="showTip(event, 'fun2', 231)" onmouseout="hideTip(event, 'fun2', 231)">s2cs</span> <span class="i" onmouseover="showTip(event, 'fun69', 232)" onmouseout="hideTip(event, 'fun69', 232)">tok</span>)
</pre>
</div>
<p><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x = 1" |&gt; s2cs |&gt; stringParser "fun";;</span><br /><span style="font-family: courier new,courier;">val it : (char list * char list) list =</span><br /><span style="font-family: courier new,courier;">&nbsp; [(['f'; 'u'; 'n'], [' '; 'x'; ' '; '='; ' '; '1'])]</span><br /><span style="font-family: courier new,courier;">&gt; "fail x = 1" |&gt; s2cs |&gt; stringParser "fun";;</span><br /><span style="font-family: courier new,courier;">val it : (char list * char list) list = []</span></p>
<p>Given a token (<i>tok</i>), we iterate through its characters, sequencing parsers that will parse that specific character (<i>t</i>). The result will be a parser (a function) that will parse a specific string out of the input string, or fail if&nbsp;it&nbsp;can't parse the string. How would we use it in our funParser? We just sequence it&hellip;</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun73', 233)" onmouseout="hideTip(event, 'fun73', 233)">funParser''</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 234)" onmouseout="hideTip(event, 'fun53', 234)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun68', 235)" onmouseout="hideTip(event, 'fun68', 235)">stringParser</span> <span class="s">"</span><span class="s">fun</span><span class="s">"</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun58', 236)" onmouseout="hideTip(event, 'fun58', 236)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun11', 237)" onmouseout="hideTip(event, 'fun11', 237)">Fun</span>)
</pre>
</div>
<p>&nbsp;</p>
<p>Now we are talking! How about parsing the whole line &ldquo;fun x = 1&rdquo;? Let&rsquo;s put together a few more &ldquo;parser combinators&rdquo; to help on that task&hellip; Every time we parse a token, we need to remove the white space after the token, so let&rsquo;s build a &ldquo;cleanSpaceParser&rdquo; which will sequence a parser, sequence a &ldquo;spaceParser&rdquo;, throwing its result away, and return the result of the first parser (see below) - using <em>cleanSpaceParser, </em>we can now build our final parsers for our single line language<em>:</em></p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun74', 238)" onmouseout="hideTip(event, 'fun74', 238)">singleSpaceParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun64', 239)" onmouseout="hideTip(event, 'fun64', 239)">tcParser</span> <span class="s">' '</span> 

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun75', 240)" onmouseout="hideTip(event, 'fun75', 240)">cleanSpaceParser</span> <span class="i" onmouseover="showTip(event, 'fun54', 241)" onmouseout="hideTip(event, 'fun54', 241)">p</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 242)" onmouseout="hideTip(event, 'fun53', 242)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun54', 243)" onmouseout="hideTip(event, 'fun54', 243)">p</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun76', 244)" onmouseout="hideTip(event, 'fun76', 244)">r</span> <span class="k">-&gt;</span>
        <span class="i" onmouseover="showTip(event, 'fun53', 245)" onmouseout="hideTip(event, 'fun53', 245)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun74', 246)" onmouseout="hideTip(event, 'fun74', 246)">singleSpaceParser</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun58', 247)" onmouseout="hideTip(event, 'fun58', 247)">returnParser</span> <span class="i" onmouseover="showTip(event, 'fun76', 248)" onmouseout="hideTip(event, 'fun76', 248)">r</span>)
    )

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun77', 249)" onmouseout="hideTip(event, 'fun77', 249)">finalFunParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun75', 250)" onmouseout="hideTip(event, 'fun75', 250)">cleanSpaceParser</span> <span class="i" onmouseover="showTip(event, 'fun73', 251)" onmouseout="hideTip(event, 'fun73', 251)">funParser''</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun78', 252)" onmouseout="hideTip(event, 'fun78', 252)">identParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun75', 253)" onmouseout="hideTip(event, 'fun75', 253)">cleanSpaceParser</span> <span class="i" onmouseover="showTip(event, 'fun18', 254)" onmouseout="hideTip(event, 'fun18', 254)">cParser</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun79', 255)" onmouseout="hideTip(event, 'fun79', 255)">equalParser</span> <span class="o">=</span> <span class="i" onmouseover="showTip(event, 'fun75', 256)" onmouseout="hideTip(event, 'fun75', 256)">cleanSpaceParser</span> <span class="o">&lt;|</span> <span class="i" onmouseover="showTip(event, 'fun64', 257)" onmouseout="hideTip(event, 'fun64', 257)">tcParser</span> <span class="s">'='</span>

<span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun80', 258)" onmouseout="hideTip(event, 'fun80', 258)">digitParser</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 259)" onmouseout="hideTip(event, 'fun53', 259)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun62', 260)" onmouseout="hideTip(event, 'fun62', 260)">satisfyParser</span> <span class="i" onmouseover="showTip(event, 'fun1', 261)" onmouseout="hideTip(event, 'fun1', 261)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun41', 262)" onmouseout="hideTip(event, 'fun41', 262)">Char</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun42', 263)" onmouseout="hideTip(event, 'fun42', 263)">IsDigit</span>, 
        <span class="i" onmouseover="showTip(event, 'fun46', 264)" onmouseout="hideTip(event, 'fun46', 264)">string</span> <span class="o">&gt;</span><span class="o">&gt;</span> <span class="i" onmouseover="showTip(event, 'fun1', 265)" onmouseout="hideTip(event, 'fun1', 265)">System</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun44', 266)" onmouseout="hideTip(event, 'fun44', 266)">Int32</span><span class="o">.</span><span class="i" onmouseover="showTip(event, 'fun45', 267)" onmouseout="hideTip(event, 'fun45', 267)">Parse</span> <span class="o">&gt;</span><span class="o">&gt;</span> <span class="i" onmouseover="showTip(event, 'fun58', 268)" onmouseout="hideTip(event, 'fun58', 268)">returnParser</span>
    )
</pre>
</div>
<p>&nbsp;</p>
<p>If we now put&nbsp;them all together, we end up with the parser for our language:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun87', 292)" onmouseout="hideTip(event, 'fun87', 292)">funLangParser</span> <span class="o">=</span> 
    <span class="i" onmouseover="showTip(event, 'fun53', 293)" onmouseout="hideTip(event, 'fun53', 293)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun77', 294)" onmouseout="hideTip(event, 'fun77', 294)">finalFunParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun88', 295)" onmouseout="hideTip(event, 'fun88', 295)">funFunc</span> <span class="k">-&gt;</span>
        <span class="i" onmouseover="showTip(event, 'fun53', 296)" onmouseout="hideTip(event, 'fun53', 296)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun78', 297)" onmouseout="hideTip(event, 'fun78', 297)">identParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun89', 298)" onmouseout="hideTip(event, 'fun89', 298)">identifier</span> <span class="k">-&gt;</span>
            <span class="i" onmouseover="showTip(event, 'fun53', 299)" onmouseout="hideTip(event, 'fun53', 299)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun79', 300)" onmouseout="hideTip(event, 'fun79', 300)">equalParser</span>, <span class="k">fun</span> _ <span class="k">-&gt;</span>
                <span class="i" onmouseover="showTip(event, 'fun53', 301)" onmouseout="hideTip(event, 'fun53', 301)">bind</span>(<span class="i" onmouseover="showTip(event, 'fun80', 302)" onmouseout="hideTip(event, 'fun80', 302)">digitParser</span>, <span class="k">fun</span> <span class="i" onmouseover="showTip(event, 'fun90', 303)" onmouseout="hideTip(event, 'fun90', 303)">digit</span> <span class="k">-&gt;</span>
                    <span class="i" onmouseover="showTip(event, 'fun58', 304)" onmouseout="hideTip(event, 'fun58', 304)">returnParser</span> (<span class="i" onmouseover="showTip(event, 'fun88', 305)" onmouseout="hideTip(event, 'fun88', 305)">funFunc</span>(<span class="i" onmouseover="showTip(event, 'fun89', 306)" onmouseout="hideTip(event, 'fun89', 306)">identifier</span>, <span class="i" onmouseover="showTip(event, 'fun90', 307)" onmouseout="hideTip(event, 'fun90', 307)">digit</span>))
                )
            )
        )
    )
</pre>
</div>
<p>&nbsp;</p>
<p>Hover your mouse again over the code above to make sure you understand what&rsquo;s going on! Does it make sense?</p>
<p>We can use a helper function to run the parser and return the results, for example:</p>
<div class="snippet">
<pre class="fssnip"><span class="k">let</span> <span class="i" onmouseover="showTip(event, 'fun91', 308)" onmouseout="hideTip(event, 'fun91', 308)">runParser</span> <span class="i" onmouseover="showTip(event, 'fun92', 309)" onmouseout="hideTip(event, 'fun92', 309)">s</span> <span class="o">=</span> 
    <span class="k">match</span> <span class="i" onmouseover="showTip(event, 'fun87', 310)" onmouseout="hideTip(event, 'fun87', 310)">funLangParser</span> (<span class="i" onmouseover="showTip(event, 'fun2', 311)" onmouseout="hideTip(event, 'fun2', 311)">s2cs</span> <span class="i" onmouseover="showTip(event, 'fun92', 312)" onmouseout="hideTip(event, 'fun92', 312)">s</span>) <span class="k">with</span>
    | [] <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun93', 313)" onmouseout="hideTip(event, 'fun93', 313)">failwith</span> <span class="s">"</span><span class="s">Error</span><span class="s"> </span><span class="s">parsing</span><span class="s"> </span><span class="s">string</span><span class="s">"</span>
    | (<span class="i" onmouseover="showTip(event, 'fun94', 314)" onmouseout="hideTip(event, 'fun94', 314)">result</span>,_)<span class="o">::</span>_ <span class="k">-&gt;</span> <span class="i" onmouseover="showTip(event, 'fun94', 315)" onmouseout="hideTip(event, 'fun94', 315)">result</span>
</pre>
</div>
<p><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt; "fun x = 1" |&gt; runParser;;</span><br /><span style="font-family: courier new,courier;">val it : FunAST = <span style="background-color: #ffff00;">Fun ('x', 1)</span></span><br /><span style="font-family: courier new,courier;">&gt; "fun y = 2" |&gt; runParser;;</span><br /><span style="font-family: courier new,courier;">val it : FunAST = <span style="background-color: #ffff00;">Fun ('y', 2)</span></span><br /><span style="font-family: courier new,courier;">&gt; "fail x = 1" |&gt; runParser;;</span><br /><span style="font-family: courier new,courier;">System.Exception: Error parsing string</span></p>
<p>It works (and looks way better than our first <em>uglyParser</em>)! We have just built a parser from scratch, congrats!</p>
<h3>Wrapping up&nbsp;</h3>
<p>&ldquo;Wow! That was a lot of code (and craziness) to just parse a single line of code&rdquo;, you might be thinking. And yes, it was indeed; but as I mentioned, we now have the building blocks to create more powerful parsers, including the JSON parser we talked about&nbsp;at the beginning of this post.</p>
<p>We started with a single character parser based on Dr. Seuss definition, and through the &ldquo;power&rdquo; computation sequencing/composition, we built more and more capable parsers. The bind, zeroParser and returnParser functions were crucial on making the compositions easier, and the use of lists as the parser&rsquo;s output provided a way to return both parsing success as well as end of computation due to an error.</p>
<p>The whole concept of functions being passed around can be a bit intimidating at first, especially if you are new to the functional lifestyle; F# Interactive can be a huge help in the learning process here. F# will also make things easier for us when we move to using computation expressions; for example, our funLangParse above could have been written as something like this:</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">let funLangParser = <br />&nbsp;parser {<br />&nbsp;&nbsp;let! funFunc = finalFunParser<br />&nbsp;&nbsp;let! identifier = identParser<br />&nbsp;&nbsp;let! _ = equalParser<br />&nbsp;&nbsp;let! digit = digitParser<br />&nbsp;&nbsp;return funFunc(identifier, digit)<br />&nbsp;}</span></p>
<p>That is exactly what we will do next: wrap our parsers into computation expressions and then build the JSON parser. Later we will&nbsp;figure out ways&nbsp;to create F# types based on the AST generated by our parsers.</p>
<p>Stay tuned!</p>
<h3>Homework</h3>
<p>The <em>cleanSpaces</em>&nbsp;parser&nbsp;only parses a single white space out of the input string. Can you rewrite it&nbsp;to parse&nbsp;any number of spaces in a way that a line like this, &ldquo;fun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp; &nbsp; =&nbsp;&nbsp;&nbsp; 7&rdquo; would be successfully parsed?</p>
<h3>Parsing JSON the fun way series</h3>
<p>&bull; <a title="Part 1: Building a parser from scratch with Dr. Seuss help (part 1)" href="http://bit.ly/qPBllg">Part 1: Building a parser from scratch with Dr. Seuss help (part 1) <br /></a>&bull; <a title="Part 2: Tricking you into Parser Monads (it's not going to hurt, I promise)" href="http://bit.ly/rl3swK">Part 2: Tricking you into Parser Monads (it's not going to hurt, I promise)<br /></a>&bull; <a title="Part 3: The JSON Parser Monad" href="http://bit.ly/rSIjjP">Part 3: The JSON Parser Monad</a></p>
<p>&nbsp;</p>
<!-- HTML code for ToolTips -->
<div id="fun1" class="tip">namespace System</div>
<div id="fun2" class="tip">val s2cs : (seq&lt;'a&gt; -&gt; 'a list)<br /><br />Full name: WebSnippets.s2cs</div>
<div id="fun3" class="tip">Multiple items <br />module List<br /><br />from Microsoft.FSharp.Collections <br /><br />--------------------<br /> <br />type List&lt;'T&gt; =<br />&nbsp;&nbsp;| ( [] )<br />&nbsp;&nbsp;| ( :: ) of 'T * 'T list<br />&nbsp;&nbsp;with<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.IEnumerable<br />&nbsp;&nbsp;&nbsp;&nbsp;interface Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;member Head : 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsEmpty : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Item : index:int -&gt; 'T with get<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Tail : 'T list<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Cons : head:'T * tail:'T list -&gt; 'T list<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Empty : 'T list<br />&nbsp;&nbsp;end<br /><br />Full name: Microsoft.FSharp.Collections.List&lt;_&gt;<br /><br />&nbsp;&nbsp;type: List&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'T&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun4" class="tip">val ofSeq : seq&lt;'T&gt; -&gt; 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.ofSeq</div>
<div id="fun5" class="tip">val cs2s : char list -&gt; String<br /><br />Full name: WebSnippets.cs2s</div>
<div id="fun6" class="tip">val cs : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun7" class="tip">type String =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : System.SByte * int * int * System.Text.Encoding -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char [] * int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;new : char * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Chars : int -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Contains : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : int * char [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member EndsWith : string * bool * System.Globalization.CultureInfo -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEnumerator : unit -&gt; System.CharEnumerator<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : char * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOf : string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member IndexOfAny : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Insert : int * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsNormalized : unit -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsNormalized : System.Text.NormalizationForm -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : char * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOf : string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LastIndexOfAny : char [] * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Normalize : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Normalize : System.Text.NormalizationForm -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadLeft : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadLeft : int * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadRight : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member PadRight : int * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Remove : int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Replace : char * char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Replace : string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * int -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : string [] * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : char [] * int * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member Split : string [] * int * System.StringSplitOptions -&gt; string []<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member StartsWith : string * bool * System.Globalization.CultureInfo -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Substring : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Substring : int * int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToCharArray : unit -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToCharArray : int * int -&gt; char []<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLower : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLower : System.Globalization.CultureInfo -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToLowerInvariant : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpper : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpper : System.Globalization.CultureInfo -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToUpperInvariant : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Trim : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member Trim : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member TrimEnd : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member TrimStart : char [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val Empty : string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * bool -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * System.Globalization.CultureInfo * System.Globalization.CompareOptions -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * string * bool * System.Globalization.CultureInfo -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * bool -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * System.StringComparison -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * bool * System.Globalization.CultureInfo -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Compare : string * int * string * int * int * System.Globalization.CultureInfo * System.Globalization.CompareOptions -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CompareOrdinal : string * string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CompareOrdinal : string * int * string * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat&lt;'T&gt; : System.Collections.Generic.IEnumerable&lt;'T&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : System.Collections.Generic.IEnumerable&lt;string&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : obj * obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Concat : string * string * string * string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Equals : string * string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Equals : string * string * System.StringComparison -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : System.IFormatProvider * string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Format : string * obj * obj * obj -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Intern : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsInterned : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNullOrEmpty : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNullOrWhiteSpace : string -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * string [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * obj [] -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join&lt;'T&gt; : string * System.Collections.Generic.IEnumerable&lt;'T&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * System.Collections.Generic.IEnumerable&lt;string&gt; -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Join : string * string [] * int * int -&gt; string<br />&nbsp;&nbsp;end<br /><br />Full name: System.String<br /><br />&nbsp;&nbsp;type: String<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fun8" class="tip">type Array =<br />&nbsp;&nbsp;class<br />&nbsp;&nbsp;&nbsp;&nbsp;member Clone : unit -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : System.Array * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member CopyTo : System.Array * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetEnumerator : unit -&gt; System.Collections.IEnumerator<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLength : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLongLength : int -&gt; int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetLowerBound : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetUpperBound : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int [] -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 [] -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int * int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 * int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int * int * int -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetValue : int64 * int64 * int64 -&gt; obj<br />&nbsp;&nbsp;&nbsp;&nbsp;member Initialize : unit -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsFixedSize : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsReadOnly : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member IsSynchronized : bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Length : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member LongLength : int64<br />&nbsp;&nbsp;&nbsp;&nbsp;member Rank : int<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SetValue : obj * int64 * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;member SyncRoot : obj<br />&nbsp;&nbsp;&nbsp;&nbsp;static member AsReadOnly&lt;'T&gt; : 'T [] -&gt; System.Collections.ObjectModel.ReadOnlyCollection&lt;'T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * obj * System.Collections.IComparer -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * 'T * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * int * int * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * int * int * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch : System.Array * int * int * obj * System.Collections.IComparer -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member BinarySearch&lt;'T&gt; : 'T [] * int * int * 'T * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Clear : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConstrainedCopy : System.Array * int * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertAll&lt;'TInput,'TOutput&gt; : 'TInput [] * System.Converter&lt;'TInput,'TOutput&gt; -&gt; 'TOutput []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * System.Array * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * System.Array * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * int * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Copy : System.Array * int64 * System.Array * int64 * int64 -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int64 [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int [] * int [] -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member CreateInstance : System.Type * int * int * int -&gt; System.Array<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Exists&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Find&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindAll&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T []<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindIndex&lt;'T&gt; : 'T [] * int * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLast&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; 'T<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member FindLastIndex&lt;'T&gt; : 'T [] * int * int * System.Predicate&lt;'T&gt; -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ForEach&lt;'T&gt; : 'T [] * System.Action&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf : System.Array * obj * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IndexOf&lt;'T&gt; : 'T [] * 'T * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf : System.Array * obj * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member LastIndexOf&lt;'T&gt; : 'T [] * 'T * int * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Resize&lt;'T&gt; : 'T [] * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Reverse : System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Reverse : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * System.Comparison&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * System.Collections.Generic.IComparer&lt;'TKey&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * int * int * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * int * int -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'T&gt; : 'T [] * int * int * System.Collections.Generic.IComparer&lt;'T&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort : System.Array * System.Array * int * int * System.Collections.IComparer -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Sort&lt;'TKey,'TValue&gt; : 'TKey [] * 'TValue [] * int * int * System.Collections.Generic.IComparer&lt;'TKey&gt; -&gt; unit<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TrueForAll&lt;'T&gt; : 'T [] * System.Predicate&lt;'T&gt; -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Array<br /><br />&nbsp;&nbsp;type: Array<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: Collections.IList<br />&nbsp;&nbsp;implements: Collections.ICollection<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable</div>
<div id="fun9" class="tip">val ofList : 'T list -&gt; 'T []<br /><br />Full name: Microsoft.FSharp.Collections.Array.ofList</div>
<div id="fun10" class="tip">type FunAST = | Fun of (char * int)<br /><br />Full name: WebSnippets.FunAST<br /><br />&nbsp;&nbsp;type: FunAST<br />&nbsp;&nbsp;implements: IEquatable&lt;FunAST&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;FunAST&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>
<div id="fun11" class="tip">union case FunAST.Fun: char * int -&gt; FunAST</div>
<div id="fun12" class="tip">Multiple items <br />val char : 'T -&gt; char (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.char <br /><br />--------------------<br /> <br />type char = Char<br /><br />Full name: Microsoft.FSharp.Core.char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun13" class="tip">Multiple items <br />val int : 'T -&gt; int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int <br /><br />--------------------<br /> <br />type int&lt;'Measure&gt; = int<br /><br />Full name: Microsoft.FSharp.Core.int&lt;_&gt;<br /><br />&nbsp;&nbsp;type: int&lt;'Measure&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IComparable&lt;int&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&lt;'Measure&gt;&gt;<br />&nbsp;&nbsp;inherits: ValueType<br /> <br /><br />--------------------<br /> <br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun14" class="tip">val charParser : char list -&gt; (char * char list) list<br /><br />Full name: WebSnippets.charParser</div>
<div id="fun15" class="tip">val chars : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun16" class="tip">type 'T list = List&lt;'T&gt;<br /><br />Full name: Microsoft.FSharp.Collections.list&lt;_&gt;<br /><br />&nbsp;&nbsp;type: 'T list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'T&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'T&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun17" class="tip">val c : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun18" class="tip">val cParser : 'a list -&gt; ('a * 'a list) list<br /><br />Full name: WebSnippets.cParser</div>
<div id="fun19" class="tip">val c : 'a</div>
<div id="fun20" class="tip">val cs : 'a list<br /><br />&nbsp;&nbsp;type: 'a list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;'a&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;'a&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun21" class="tip">val uglyParser : char list -&gt; (FunAST * char list) list<br /><br />Full name: WebSnippets.uglyParser</div>
<div id="fun22" class="tip">val c1 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun23" class="tip">val cs1 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun24" class="tip">val head : 'T list -&gt; 'T<br /><br />Full name: Microsoft.FSharp.Collections.List.head</div>
<div id="fun25" class="tip">val c2 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun26" class="tip">val cs2 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun27" class="tip">val c3 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun28" class="tip">val cs3 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun29" class="tip">val c4 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun30" class="tip">val cs4 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun31" class="tip">val c5 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun32" class="tip">val cs5 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun33" class="tip">val c6 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun34" class="tip">val cs6 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun35" class="tip">val c7 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun36" class="tip">val cs7 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun37" class="tip">val c8 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun38" class="tip">val cs8 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun39" class="tip">val c9 : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun40" class="tip">val cs9 : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun41" class="tip">type Char =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : char<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertFromUtf32 : int -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertToUtf32 : char * char -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ConvertToUtf32 : string * int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetNumericValue : char -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetNumericValue : string * int -&gt; float<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetUnicodeCategory : char -&gt; System.Globalization.UnicodeCategory<br />&nbsp;&nbsp;&nbsp;&nbsp;static member GetUnicodeCategory : string * int -&gt; System.Globalization.UnicodeCategory<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsControl : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsControl : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsDigit : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsDigit : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsHighSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsHighSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetter : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetter : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetterOrDigit : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLetterOrDigit : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLowSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLowSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLower : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsLower : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNumber : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsNumber : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPunctuation : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsPunctuation : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSeparator : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSeparator : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogate : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogate : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogatePair : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSurrogatePair : char * char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSymbol : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsSymbol : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsUpper : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsUpper : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsWhiteSpace : char -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member IsWhiteSpace : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLower : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLower : char * System.Globalization.CultureInfo -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToLowerInvariant : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToString : char -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpper : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpper : char * System.Globalization.CultureInfo -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member ToUpperInvariant : char -&gt; char<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * char -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Char<br /><br />&nbsp;&nbsp;type: Char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun42" class="tip">Multiple overloads <br />Char.IsDigit(c: char) : bool <br />Char.IsDigit(s: string, index: int) : bool</div>
<div id="fun43" class="tip">val num : int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun44" class="tip">type Int32 =<br />&nbsp;&nbsp;struct<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : obj -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member CompareTo : int -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : obj -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member Equals : int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetHashCode : unit -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;member GetTypeCode : unit -&gt; System.TypeCode<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : unit -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;member ToString : string * System.IFormatProvider -&gt; string<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MaxValue : int<br />&nbsp;&nbsp;&nbsp;&nbsp;static val MinValue : int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.IFormatProvider -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -&gt; int<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * int -&gt; bool<br />&nbsp;&nbsp;&nbsp;&nbsp;static member TryParse : string * System.Globalization.NumberStyles * System.IFormatProvider * int -&gt; bool<br />&nbsp;&nbsp;end<br /><br />Full name: System.Int32<br /><br />&nbsp;&nbsp;type: Int32<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun45" class="tip">Multiple overloads <br />Int32.Parse(s: string) : int <br />Int32.Parse(s: string, provider: IFormatProvider) : int <br />Int32.Parse(s: string, style: Globalization.NumberStyles) : int <br />Int32.Parse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider) : int</div>
<div id="fun46" class="tip">Multiple items <br />val string : 'T -&gt; string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string <br /><br />--------------------<br /> <br />type string = String<br /><br />Full name: Microsoft.FSharp.Core.string<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fun47" class="tip">val sequence : (char list -&gt; ('a * char list) list) * ('a -&gt; char list -&gt; ('b * char list) list) -&gt; char list -&gt; ('b * char list) list<br /><br />Full name: WebSnippets.sequence</div>
<div id="fun48" class="tip">val aParser : (char list -&gt; ('a * char list) list)</div>
<div id="fun49" class="tip">val continutationFunc : ('a -&gt; char list -&gt; ('b * char list) list)</div>
<div id="fun50" class="tip">val c' : 'a</div>
<div id="fun51" class="tip">val cs' : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun52" class="tip">val bParser : (char list -&gt; ('b * char list) list)</div>
<div id="fun53" class="tip">val bind : (char list -&gt; ('a * char list) list) * ('a -&gt; char list -&gt; ('b * char list) list) -&gt; char list -&gt; ('b * char list) list<br /><br />Full name: WebSnippets.bind</div>
<div id="fun54" class="tip">val p : (char list -&gt; ('a * char list) list)</div>
<div id="fun55" class="tip">val f : ('a -&gt; char list -&gt; ('b * char list) list)</div>
<div id="fun56" class="tip">val uglyFunParser : char list -&gt; ((char * int -&gt; FunAST) * char list) list<br /><br />Full name: WebSnippets.uglyFunParser</div>
<div id="fun57" class="tip">val input : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun58" class="tip">val returnParser : 'a -&gt; 'b -&gt; ('a * 'b) list<br /><br />Full name: WebSnippets.returnParser</div>
<div id="fun59" class="tip">val something : 'a</div>
<div id="fun60" class="tip">val cs : 'b</div>
<div id="fun61" class="tip">val zeroParser : unit -&gt; 'a -&gt; 'b list<br /><br />Full name: WebSnippets.zeroParser</div>
<div id="fun62" class="tip">val satisfyParser : (char -&gt; bool) -&gt; (char list -&gt; (char * char list) list)<br /><br />Full name: WebSnippets.satisfyParser</div>
<div id="fun63" class="tip">val pred : (char -&gt; bool)</div>
<div id="fun64" class="tip">val tcParser : char -&gt; (char list -&gt; (char * char list) list)<br /><br />Full name: WebSnippets.tcParser</div>
<div id="fun65" class="tip">val funParser : char list -&gt; ((char * int -&gt; FunAST) * char list) list<br /><br />Full name: WebSnippets.funParser</div>
<div id="fun66" class="tip">val internalParser : (char list -&gt; ((char * int -&gt; FunAST) * char list) list)</div>
<div id="fun67" class="tip">val funParser' : (char list -&gt; ((char * int -&gt; FunAST) * char list) list)<br /><br />Full name: WebSnippets.funParser'</div>
<div id="fun68" class="tip">val stringParser : string -&gt; (char list -&gt; (char list * char list) list)<br /><br />Full name: WebSnippets.stringParser</div>
<div id="fun69" class="tip">val tok : string<br /><br />&nbsp;&nbsp;type: string<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: ICloneable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;string&gt;<br />&nbsp;&nbsp;implements: seq&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable<br />&nbsp;&nbsp;implements: IEquatable&lt;string&gt;</div>
<div id="fun70" class="tip">val text : (char list -&gt; char list -&gt; (char list * char list) list)</div>
<div id="fun71" class="tip">val t : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun72" class="tip">val tok' : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun73" class="tip">val funParser'' : (char list -&gt; ((char * int -&gt; FunAST) * char list) list)<br /><br />Full name: WebSnippets.funParser''</div>
<div id="fun74" class="tip">val singleSpaceParser : (char list -&gt; (char * char list) list)<br /><br />Full name: WebSnippets.singleSpaceParser</div>
<div id="fun75" class="tip">val cleanSpaceParser : (char list -&gt; ('a * char list) list) -&gt; (char list -&gt; ('a * char list) list)<br /><br />Full name: WebSnippets.cleanSpaceParser</div>
<div id="fun76" class="tip">val r : 'a</div>
<div id="fun77" class="tip">val finalFunParser : (char list -&gt; ((char * int -&gt; FunAST) * char list) list)<br /><br />Full name: WebSnippets.finalFunParser</div>
<div id="fun78" class="tip">val identParser : (char list -&gt; (char * char list) list)<br /><br />Full name: WebSnippets.identParser</div>
<div id="fun79" class="tip">val equalParser : (char list -&gt; (char * char list) list)<br /><br />Full name: WebSnippets.equalParser</div>
<div id="fun80" class="tip">val digitParser : (char list -&gt; (int * char list) list)<br /><br />Full name: WebSnippets.digitParser</div>
<div id="fun81" class="tip">val spaceParser : char list -&gt; (char list * char list) list<br /><br />Full name: WebSnippets.spaceParser</div>
<div id="fun82" class="tip">val emptyParser : (char list -&gt; (char list * char list) list)</div>
<div id="fun83" class="tip">val a : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun84" class="tip">val x : char list * char list</div>
<div id="fun85" class="tip">val xs : (char list * char list) list<br /><br />&nbsp;&nbsp;type: (char list * char list) list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char list * char list&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char list * char list&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun86" class="tip">val aa : char list<br /><br />&nbsp;&nbsp;type: char list<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;List&lt;char&gt;&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable<br />&nbsp;&nbsp;implements: Collections.Generic.IEnumerable&lt;char&gt;<br />&nbsp;&nbsp;implements: Collections.IEnumerable</div>
<div id="fun87" class="tip">val funLangParser : (char list -&gt; (FunAST * char list) list)<br /><br />Full name: WebSnippets.funLangParser</div>
<div id="fun88" class="tip">val funFunc : (char * int -&gt; FunAST)</div>
<div id="fun89" class="tip">val identifier : char<br /><br />&nbsp;&nbsp;type: char<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;char&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;char&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun90" class="tip">val digit : int<br /><br />&nbsp;&nbsp;type: int<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: IFormattable<br />&nbsp;&nbsp;implements: IConvertible<br />&nbsp;&nbsp;implements: IComparable&lt;int&gt;<br />&nbsp;&nbsp;implements: IEquatable&lt;int&gt;<br />&nbsp;&nbsp;inherits: ValueType</div>
<div id="fun91" class="tip">val runParser : seq&lt;char&gt; -&gt; FunAST<br /><br />Full name: WebSnippets.runParser</div>
<div id="fun92" class="tip">val s : seq&lt;char&gt;<br /><br />&nbsp;&nbsp;type: seq&lt;char&gt;<br />&nbsp;&nbsp;inherits: Collections.IEnumerable</div>
<div id="fun93" class="tip">val failwith : string -&gt; 'T<br /><br />Full name: Microsoft.FSharp.Core.Operators.failwith</div>
<div id="fun94" class="tip">val result : FunAST<br /><br />&nbsp;&nbsp;type: FunAST<br />&nbsp;&nbsp;implements: IEquatable&lt;FunAST&gt;<br />&nbsp;&nbsp;implements: Collections.IStructuralEquatable<br />&nbsp;&nbsp;implements: IComparable&lt;FunAST&gt;<br />&nbsp;&nbsp;implements: IComparable<br />&nbsp;&nbsp;implements: Collections.IStructuralComparable</div>]]></content:encoded>
    </item>
    <item>
      <title>WM 6 SDK and Cellular Emulator (Can you hear me now?)</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/wm-6-sdk-and-cellular-emulator-can-you-hear-me-now</link>
      <pubDate>Wed, 11 Apr 2007 13:51:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2007/04/11/wm-6-sdk-and-cellular-emulator-can-you-hear-me-now/</guid>
      <description><![CDATA[You may have noticed that the emulator images shipped in the WM 6 SDKs have no cellular signal,...]]></description>
      <content:encoded><![CDATA[<P>You may have noticed that the emulator images shipped in the WM 6 SDKs have no cellular signal, which is very different from the previous SDKs where all images used to be connected to the <EM>Fake Network</EM>. We had to make this change to introduce the new Cellular Emulator tool. WM 5.0 SDKs’ images use&nbsp;a technology we call <EM>FakeRIL</EM>, or the Fake Radio Interface Layer, and although it allowed developers to call and send SMS from within the Device Emulator (see <A class="" href="http://blogs.msdn.com/fzandona/archive/2005/12/07/501206.aspx" mce_href="http://blogs.msdn.com/fzandona/archive/2005/12/07/501206.aspx">Windows Mobile Device Emulator phone numbers</A> for some examples), Cellular Emulator offers more options and it makes it easier to test your applications. </P>
<P>Here is some information on how to run Cellular Emulator and configure emulator image's network settings to browse to the Internet. Once you configure the emulator images, you can save their states (from Device Emulator) to speed up the process.</P>
<H3>Cellular Emulator</H3>
<P>Cellular Emulator is a software-based emulator to aid developers and testers in developing and testing their software under the Windows Embedded CE and Windows Mobile platforms. The design goal of Cellular Emulator is to replace the radio module in both development and test environments. The advantage of Cellular Emulator is that it provides not only voice but also data connectivity. Moreover, Cellular Emulator is a powerful tool to test various applications under different wireless network conditions in GSM/GPRS and/or UMTS networks. </P>
<H4>Running Cellular Emulator</H4>
<OL xmlns="">
<LI>Launch the Cellular Emulator (<B>Start</B>/<B>All Programs</B> / <B>Windows Mobile 6 SDK</B> / <B>Tools</B> / <B>Cellular Emulator</B> ) and the Device Emulator. </LI>
<LI>Read the COM port configuration from the status bar of the Cellular Emulator main window. </LI>
<LI>In the Device Emulator, go to <B>File</B> / <B>Configure</B> and select the <B>Peripherals</B> tab. </LI>
<LI>Map the Serial port 0 of Device Emulator to the specific COM number obtained from step 2 </LI>
<LI>Soft reset the Device Emulator (<B>File</B> / <B>Reset</B> / <B>Soft</B>). </LI></OL>
<H4>Shutting the Cellular Emulator</H4>
<P>The close button of the Cellular Emulator main windows will only send the application to the tray panel. To close the application, right click the tray icon and select Exit. </P>
<H4>Cellular Emulator Data Connections </H4>
<P>The Cellular Emulator will also provide GPRS connection simulation. Users can create simulated GPRS connections just like common ones. The access point name and user name/password are not checked and thus may be anything. Once the data connection is made, the emulator will just act as if it is connected to the network of the host machine. If some proxy settings are needed for the host machine to set up connections to remote machines, they are also needed on the emulator. Assume a network environment where HTTP proxy is needed to access external web sites. Setting samples on Windows Mobile 6 Standard and Professional are provided in the following sections.</P><STRONG><U>Windows Mobile 6 Standard</U></STRONG> 
<OL>
<LI>Enter <STRONG>Start-Settings-Connections-GPRS-Menu-Add</STRONG>. Create a GPRS connection using the settings as follows. 
<UL>
<LI>Name: PPP </LI>
<LI>Connects to: WAP </LI>
<LI>Network Access Point: Some Access Point Name </LI>
<LI>User Name: Just leave blank for anonymous configuration </LI></UL></LI>
<LI>(Optional) Enter <B>Start-Settings-Connections-Proxy-Menu-Add</B>. Create a proxy using the following settings. 
<UL>
<LI>Description: Proxy </LI>
<LI>Connects from: WAP Network </LI>
<LI>Connects to: The Internet </LI>
<LI>Address: The proxy in the specified user's network </LI></UL></LI>
<LI>Enter <B>Start-Settings-Connections-Menu-Advanced</B>. 
<UL>
<LI>Set Internet connection to PPP </LI>
<LI>Set WAP connection to PPP </LI>
<LI>Leave the others as automatic </LI></UL></LI>
<LI>Enter Internet Explorer Mobile, and choose <B>Menu</B>-<B>Tools</B>-<B>Options</B>-<B>Connections</B>, then configure the Internet Explorer Mobile settings: 
<UL>
<LI>Automatically detect settings: CHECKED </LI>
<LI>Select network: The Internet </LI></UL></LI>
<LI>Choose the Internet Explorer Mobile icon using the arrow key on the keyboard. </LI>
<LI>Browse freely using Internet Explorer Mobile. </LI></OL><STRONG><U>Windows Mobile 6 Professional</U></STRONG> 
<OL>
<LI>If the user's computer uses a proxy to access the Internet, then the user needs to setup a <B>Work Connection</B> on the Pocket PC, otherwise the user can setup an <B>Internet Connection</B>.</LI>
<LI>Setup a GPRS connection. Access point and user name can be empty. </LI>
<LI>(Optional) Setup a proxy. This should be the full name of a working proxy required by the corporate network. </LI>
<LI>Open Internet Explorer Mobile and browse to a web site. </LI></OL>
<H3>Makeover</H3>
<P>Out of curiosity, Cellular Emulator went through an extreme makeover from the first time I learned about it as an internal tool, to its release in the Windows Mobile 6 SDK.</P>
<P mce_keep="true">I hope you enjoy it and let me know your feedback!</P>
<P mce_keep="true"><STRONG><U>Before:</U></STRONG></P><IMG title="Cellular Emulator - Before" style="WIDTH: 507px; HEIGHT: 152px" height=152 alt="Cellular Emulator - Before" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/02/08/91/17/CellEmuBefore.jpg" original-url="http://blogs.msdn.com/photos/fzandona/images/2089117/original.aspx" width=507> 
<P mce_keep="true"><STRONG><U>After:</U></STRONG></P>
<P><IMG title="Cellular Emulator - After" style="WIDTH: 441px; HEIGHT: 404px" height=404 alt="Cellular Emulator - After" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/02/08/91/27/CellEmuAfter.jpg" original-url="http://blogs.msdn.com/photos/fzandona/images/2089127/original.aspx" width=441></P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>WM 6 SDK Install Issue: Common7IDEProjectTemplates?</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/wm-6-sdk-install-issue-common7ideprojecttemplates</link>
      <pubDate>Fri, 30 Mar 2007 13:07:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2007/03/30/wm-6-sdk-install-issue-common7ideprojecttemplates/</guid>
      <description><![CDATA[If you are installing the WM 6 SDK on Windows Vista you may hit an error that blocks the...]]></description>
      <content:encoded><![CDATA[<P>If you are installing the WM 6 SDK on Windows Vista you may hit an error that blocks the installation. The error message is:</P>
<P><EM>Could not access network location Common7\IDE\ProjectTemplates</EM></P>
<P>This issue is related to a Custom Action (VBScript) we were using to install the Project Templates for Visual Studio - Vista may be blocking VBScript (through security policy, for example) which then causes our installation to fail. If you log the SDK setup, you will see something like:</P>
<P><EM>DEBUG: Error 2738:&nbsp; Could not access VBScript runtime for custom action</EM></P>
<P>While we work on that for the SDK Refresh, here is a simple workaround that will&nbsp;allow you to install the SDKs:</P>
<OL>
<LI>Click on <STRONG>Start</STRONG> / <STRONG>All Programs</STRONG> / <STRONG>Accessories</STRONG>;</LI>
<LI>Right click on <STRONG>Command Prompt</STRONG> and click on <STRONG>Run as administrator</STRONG>;</LI>
<LI>Click on <STRONG>Continue</STRONG> in the <STRONG>User Account Control</STRONG> pop-up;</LI>
<LI>In the <STRONG>Command Prompt</STRONG> window run the following command: <EM>regsvr32 %SystemRoot%\system32\vbscript.dll</EM></LI>
<LI>Close the <STRONG>Command Prompt</STRONG> window and install the SDKs normally.</LI></OL>
<P>Please, let me know if that works for you (and yes, we don't like VBScript CAs&nbsp;anymore too! :-)</P>
<P>See you at MEDC 2007!</P>]]></content:encoded>
    </item>
    <item>
      <title>Windows Mobile 6 SDKs are now available!</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/windows-mobile-6-sdks-are-now-available</link>
      <pubDate>Thu, 01 Mar 2007 07:44:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2007/03/01/windows-mobile-6-sdks-are-now-available/</guid>
      <description><![CDATA[The button was pushed and the Windows Mobile 6 SDKs are now available – you can download both...]]></description>
      <content:encoded><![CDATA[<P>The <EM>button was pushed</EM> and the Windows Mobile 6 SDKs are now available – you can download both “Windows Mobile 6 Standard SDK” and “Windows Mobile 6 Professional SDK” <A class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=06111A3A-A651-4745-88EF-3D48091A390B&amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=06111A3A-A651-4745-88EF-3D48091A390B&amp;displaylang=en">here</A>!</P>
<P>Please, read carefully the download page details to learn about the new naming and emulator images, requirements and know issues. Make sure to also read the <A class="" href="http://msdn2.microsoft.com/en-us/library/bb278115.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/bb278115.aspx">What's New for Developers in Windows Mobile 6</A> white-paper.</P>
<P>The table shows which SDK must be used when targeting the old Smartphone and Pocket PC categories:</P>
<TABLE class="" border=1>
<TBODY>
<TR>
<TD class=""><STRONG>Previous Categories</STRONG></TD>
<TD class=""><STRONG>New Categories</STRONG></TD>
<TD class=""><STRONG>Windows Mobile SDK</STRONG></TD></TR>
<TR>
<TD class="">Windows Mobile for Smartphone</TD>
<TD class="">Windows Mobile Standard</TD>
<TD class="">Windows Mobile 6 Standard SDK</TD></TR>
<TR>
<TD class="">Windows Mobile for Pocket PC</TD>
<TD class="">Windows Mobile Classic</TD>
<TD class="" rowSpan=2>Windows Mobile 6 Professional SDK</TD></TR>
<TR>
<TD class="">Windows Mobile for Pocket PC Phone Edition</TD>
<TD class="">Windows Mobile Professional</TD></TR></TBODY></TABLE>
<P mce_keep="true"><U><STRONG>What’s new in the Windows Mobile 6 SDK?</STRONG><BR></U>Here is a quick overview of the new SDKs.</P>
<P mce_keep="true"><STRONG>Better discoverability</STRONG><BR>Everything is installed (by default) under C:\Program Files\Windows Mobile 6 SDK. We also “share” the common content from both SDKs,&nbsp;for example, there will be only one help collection, only one set of common samples, tools, etc., even if you install both SDKs. Readme files are also better, go to Start Menu, Programs, Windows Mobile SDK and check the main readme file as well as the tools and samples ones.</P>
<P mce_keep="true"><STRONG>Help Collection<BR></STRONG>The help is now integrated with DocExplorer, but you can still access it through the Start Menu if you want/need to.</P>
<P mce_keep="true"><STRONG>Samples</STRONG><BR>We have samples! A lot of them! Check the Samples readme file to learn about all sample collection.</P>
<P mce_keep="true"><STRONG>New Tools<BR></STRONG>There are also a nice number of new tools with this release. Here is a quick list with a brief explanation of each one:</P>
<P mce_keep="true"><U>Cellular Emulator v1<BR></U>Cellular Emulator is a software-based emulator to aid developers and testers in developing and testing their software under the Windows Mobile platforms. The design goal of Cellular Emulator is to replace the radio module in both development and test environments. The advantage of Cellular Emulator is that it provides not only voice but also data connectivity. Moreover, Cellular Emulator is a powerful tool to test various applications under different wireless network conditions in GSM/GPRS and/or UMTS networks.</P>
<P mce_keep="true">In other words: it is your own Mobile Operator running on your desktop :-). You can call your device emulator, send and receive SMS, play with AT commands, SIM cards, etc. How cool is that?</P>
<P mce_keep="true"><U>Device Emulator v2<BR></U>Yes, it is here – install the SDK and have Device Emulator v2 up and running on your machine.</P>
<P mce_keep="true"><U>Local Server Framework<BR></U>The Local Server Framework allows users to develop custom server applications running over localhost. Components of Windows Mobile powered devices must communicate with external services running on external servers. Lack of control over the external server inhibits the ability to comprehensively test client side code. Additionally, varying network conditions in build labs introduce multiple points of failure in test code that are often unrelated to code under test. The server framework allows development of test application servers that run locally over localhost on the device, alleviating these problems. The Local (or Fake) Server Framework allows users to develop either full-featured servers or application-specific servers that communicate with their respective clients.</P>
<P><U>FakeGPS &amp; GPS Settings<BR></U>Do you want to develop a GPS-enable application but don’t have a real GPS device? FakeGPS is the answer! Just drop and install the FakeGPS.cab file into your emulator or device and you are ready to go. FakeGPS will set the GPS Intermediate Driver to read the NMEA strings from a text file instead of using a real GPS device. </P>
<P>And what happens if you want to sell your GPS-enabled applications to WM 6 Standard users? You can use GPSSettings to enables Windows Mobile 6 Standard users to configure the GPS intermediate driver, it works in the same way as the built-in GPS settings applet on Windows Mobile 6 Professional and Windows Mobile 6 Classic – better yet, you can even redistribute GPSSettings.exe with your applications!</P>
<P><U>Hopper<BR></U>Hopper is a software test tool that simulates input stress on Windows Mobile powered devices. Hopper will stress all applications that are available through the menu system by rapidly sending keystrokes and screen taps in a random fashion. By sending a large number of user inputs very rapidly, Hopper can quickly isolate troublesome scenarios and find bugs in your applications.</P>
<P>It works like this: you setup Hopper to test your application and let it run. It keeps clicking around randomly on your application going through “code paths” that you would not usually test, and of course, it finds bugs!</P>
<P><U>New Emulator Image<BR></U>A brand new “Windows Mobile 6 Professional Square QVGA (320x320 pixels - 128 dpi)” emulator image!</P>
<P><U>CabSignTool<BR></U>CabSignTool signs a .cab file and all its executable content (.exe, .dll) with the specified certificate – it unpacks the .cab file, signs all .exe and .dll files, pack the .cab file again and sign it, in one single pass.</P><BR>
<P>How do you like it? Stick around as I will continue posting about the SDK, tips and tricks, issues, etc. And let me know your comments and feedback.</P>
<P>Enjoy the new Windows Mobile 6 SDKs!</P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Certificates in Windows Mobile 6</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/certificates-in-windows-mobile-6</link>
      <pubDate>Fri, 09 Feb 2007 04:02:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2007/02/09/certificates-in-windows-mobile-6/</guid>
      <description><![CDATA[Scott Yost talks about the certificate changes that we made in Windows Mobile 6:
It gives me great...]]></description>
      <content:encoded><![CDATA[<P>Scott Yost talks about the certificate changes that we made in Windows Mobile 6:</P>
<P><EM>It gives me great pleasure to announce the following changes that we made in WM6:</EM></P>
<UL>
<LI><EM>Certificate Installer built into the platform&nbsp;</EM></LI>
<UL>
<LI><EM>Installs CER, P7B, and PFX files&nbsp;</EM></LI>
<LI><EM>No more Access Denied messages.&nbsp;</EM></LI>
<LI><EM>Installs certs to the ROOT, Intermediate, and MY store</EM></LI></UL>
<LI><EM>Wildcard Certificate support for SSL</EM></LI></UL>
<P>Full post <A class="" href="http://blogs.msdn.com/windowsmobile/archive/2007/02/07/certificate-improvements-in-windows-mobile-6.aspx" mce_href="http://blogs.msdn.com/windowsmobile/archive/2007/02/07/certificate-improvements-in-windows-mobile-6.aspx">here</A>.</P>]]></content:encoded>
    </item>
    <item>
      <title>Windows Mobile 6 SDK</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/windows-mobile-6-sdk</link>
      <pubDate>Thu, 08 Feb 2007 18:39:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2007/02/08/windows-mobile-6-sdk/</guid>
      <description><![CDATA[With the Windows Mobile 6 announcement it is time to start talking about the new SDK we put together...]]></description>
      <content:encoded><![CDATA[<P>With the Windows Mobile 6 announcement it is time to start talking about the new SDK we put together for this release (and I can finally tell you what I’ve been working with since I arrived here). We have been working hard on it and we all hope you'll enjoy it as much as we do :-)</P>
<P><STRONG>What’s new for developers?</STRONG></P>
<OL>
<LI>Great application compatibility for Windows Mobile 5 applications</LI>
<LI>.NET Compact Framework v2 SP1 in the ROM!</LI>
<LI>SQL Server Compact Edition in the ROM!</LI>
<LI>New APIs</LI>
<UL>
<LI>New Sound APIs</LI>
<LI>WISP Lite (Yes, the same WISP technology from the TabletPC!)</LI></UL>
<LI>Several new tools:</LI>
<UL>
<LI>Cellular Emulator (kind of&nbsp;having your own&nbsp;Mobile Operator ;)</LI>
<LI>Local Server Framework (aka FakeServer)</LI>
<LI>FakeGPS</LI>
<LI>Hopper</LI>
<LI>CabToolSigner</LI>
<LI>Security Configuration Manager</LI></UL>
<LI>New emulator images</LI>
<LI>Platform improvements</LI>
<LI>Integrated documentation</LI></OL>
<P>Overall Windows Mobile 6&nbsp;SDK makes it easier to develop, build, test and deploy your applications. </P>
<P>I’ll drill down into the SDK details on my next posts – so stay tuned!</P>]]></content:encoded>
    </item>
    <item>
      <title>ScreenLib for Windows Mobile - no resolution/orientation headaches any more!</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/screenlib-for-windows-mobile-no-resolutionorientation-headaches-any-more</link>
      <pubDate>Mon, 11 Sep 2006 13:22:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2006/09/11/screenlib-for-windows-mobile-no-resolutionorientation-headaches-any-more/</guid>
      <description><![CDATA[Mel has developed and posted a great library for those of you developing native code - on his own...]]></description>
      <content:encoded><![CDATA[<P><A href="http://blogs.msdn.com/melsam/">Mel</A> has developed and posted a great library for those of you developing native code - on his own words:</P>
<P><EM>I'm proud to announce ScreenLib, a new library for native Windows Mobile developers. It takes away a lot of the pain of designing user interfaces for multiple screen sizes, orientations, form factors etc. It lets you create a user interface once and have it automatically adapt to whatever the device’s screen size is at runtime. By doing this, it offers basic docking &amp; anchoring support for native development and can do a lot of UI plumbing work with just 1 or 2 lines of code. </EM></P>
<P><EM>ScreenLib works on Pocket PC and Smartphone devices, so it's a great step towards creating single binaries that will run on both platforms.</EM></P>
<P><EM>I highly recommend watching a video tutorial that explains how ScreenLib works and why it should be used. To download the video, please visit:<BR></EM><A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a908dd7f-71c0-4cea-b97d-b9ffe985f903&amp;displaylang=en."><EM>http://www.microsoft.com/downloads/details.aspx?FamilyID=a908dd7f-71c0-4cea-b97d-b9ffe985f903&amp;displaylang=en.</EM></A></P>
<P><EM>To download ScreenLib for free, please click: </EM><A href="http://blogs.msdn.com/windowsmobile/attachment/749467.ashx"><EM>ScreenLib.zip</EM></A></P>
<P>He has presented it&nbsp;here a couple of weeks ago and I was impressed by its simplicity and how it can increase your productivity when dealing with screen orientation/resolution, etc. And as Mel says, we’d like to hear your feedback!</P>
<P>Thanks Mel!</P>]]></content:encoded>
    </item>
    <item>
      <title>Check out the new Windows Mobile Network Analyzer PowerToy!</title>
      <link>https://docs.microsoft.com/archive/blogs/fzandona/check-out-the-new-windows-mobile-network-analyzer-powertoy</link>
      <pubDate>Fri, 08 Sep 2006 17:09:00 GMT</pubDate>
      <dc:creator><![CDATA[fzandona]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/fzandona/2006/09/08/check-out-the-new-windows-mobile-network-analyzer-powertoy/</guid>
      <description><![CDATA[Network Analyzer for Windows Mobile was released today as a PowerToy:
OverviewNetwork Analyzer...]]></description>
      <content:encoded><![CDATA[<IMG src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/00/74/68/51/WMNA.jpg" original-url="http://blogs.msdn.com/photos/fzandona/images/746851/original.aspx" align=right border=1>
<P>Network Analyzer for Windows Mobile was released today as a PowerToy:</P>
<P><EM><STRONG>Overview<BR></STRONG></EM><EM>Network Analyzer for Windows Mobile runs network utilities, for example ping and ipconfig, on a Windows Mobile powered device. Network Analyzer for Windows Mobile facilitates the troubleshooting of network connectivity issues. You can extend the harness. You can add user-defined tests (DLLs) to the list of tests to be executed. An xml input file defines the list of tests to execute. You can use Network Analyzer to send information about network traffic to a .cap file. You can then view the .cap file with the Network Monitor tool or the Ethereal tool. See the readme file below for more information.</EM></P>
<P>You can download it <A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=081c6401-49d4-4506-a03b-c41bc76c2f51&amp;displaylang=en">here</A>.</P>
<P>Enjoy it!</P>]]></content:encoded>
    </item>
  </channel>
</rss>