Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / doc / guide / localhost / NumericLiteral
CommitLineData
7f918cf1
CE
1<!DOCTYPE html>\r
2<html lang="en">\r
3<head>\r
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r
5<meta name="generator" content="AsciiDoc 8.6.9">\r
6<title>NumericLiteral</title>\r
7<link rel="stylesheet" href="./asciidoc.css" type="text/css">\r
8<link rel="stylesheet" href="./pygments.css" type="text/css">\r
9\r
10\r
11<script type="text/javascript" src="./asciidoc.js"></script>\r
12<script type="text/javascript">\r
13/*<![CDATA[*/\r
14asciidoc.install();\r
15/*]]>*/\r
16</script>\r
17<link rel="stylesheet" href="./mlton.css" type="text/css">\r
18</head>\r
19<body class="article">\r
20<div id="banner">\r
21<div id="banner-home">\r
22<a href="./Home">MLton 20180207</a>\r
23</div>\r
24</div>\r
25<div id="header">\r
26<h1>NumericLiteral</h1>\r
27</div>\r
28<div id="content">\r
29<div id="preamble">\r
30<div class="sectionbody">\r
31<div class="paragraph"><p>Numeric literals in <a href="StandardML">Standard ML</a> can be written in either\r
32decimal or hexadecimal notation. Sometimes it can be convenient to\r
33write numbers down in other bases. Fortunately, using <a href="Fold">Fold</a>, it is\r
34possible to define a concise syntax for numeric literals that allows\r
35one to write numeric constants in any base and of various types\r
36(<span class="monospaced">int</span>, <span class="monospaced">IntInf.int</span>, <span class="monospaced">word</span>, and more).</p></div>\r
37<div class="paragraph"><p>We will define constants <span class="monospaced">I</span>, <span class="monospaced">II</span>, <span class="monospaced">W</span>, and <span class="monospaced">`</span> so\r
38that, for example,</p></div>\r
39<div class="listingblock">\r
40<div class="content"><div class="highlight"><pre><span class="n">I</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="n">`</span><span class="mi">1</span><span class="n">`</span><span class="mi">2</span><span class="n">`</span><span class="mi">3</span><span class="w"> </span><span class="n">$</span><span class="w"></span>\r
41</pre></div></div></div>\r
42<div class="paragraph"><p>denotes <span class="monospaced">123:int</span> in base 10, while</p></div>\r
43<div class="listingblock">\r
44<div class="content"><div class="highlight"><pre><span class="n">II</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="n">`</span><span class="mi">2</span><span class="n">`</span><span class="mi">3</span><span class="w"> </span><span class="n">$</span><span class="w"></span>\r
45</pre></div></div></div>\r
46<div class="paragraph"><p>denotes <span class="monospaced">19:IntInf.int</span> in base 8, and</p></div>\r
47<div class="listingblock">\r
48<div class="content"><div class="highlight"><pre><span class="n">W</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">`</span><span class="mi">1</span><span class="n">`</span><span class="mi">1</span><span class="n">`</span><span class="mi">0</span><span class="n">`</span><span class="mi">1</span><span class="w"> </span><span class="n">$</span><span class="w"></span>\r
49</pre></div></div></div>\r
50<div class="paragraph"><p>denotes <span class="monospaced">0w13: word</span>.</p></div>\r
51<div class="paragraph"><p>Here is the code.</p></div>\r
52<div class="listingblock">\r
53<div class="content"><div class="highlight"><pre><span class="k">structure</span><span class="w"> </span><span class="n">Num</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
54<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
55<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">make</span><span class="w"> </span><span class="p">(</span><span class="k">op</span><span class="w"> </span><span class="n">*</span><span class="p">,</span><span class="w"> </span><span class="k">op</span><span class="w"> </span><span class="n">+</span><span class="p">,</span><span class="w"> </span><span class="n">i2x</span><span class="p">)</span><span class="w"> </span><span class="n">iBase</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
56<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
57<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">xBase</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">i2x</span><span class="w"> </span><span class="n">iBase</span><span class="w"></span>\r
58<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
59<span class="w"> </span><span class="n">Fold</span><span class="p">.</span><span class="n">fold</span><span class="w"></span>\r
60<span class="w"> </span><span class="p">((</span><span class="n">i2x</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"></span>\r
61<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"></span>\r
62<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">&lt;=</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">andalso</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">&lt;</span><span class="w"> </span><span class="n">iBase</span><span class="w"> </span><span class="k">then</span><span class="w"></span>\r
63<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">xBase</span><span class="w"> </span><span class="n">+</span><span class="w"> </span><span class="n">i2x</span><span class="w"> </span><span class="n">i</span><span class="w"></span>\r
64<span class="w"> </span><span class="k">else</span><span class="w"></span>\r
65<span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Fail</span><span class="w"> </span><span class="p">(</span><span class="n">concat</span><span class="w"></span>\r
66<span class="w"> </span><span class="p">[</span><span class="s">&quot;Num: &quot;</span><span class="p">,</span><span class="w"> </span><span class="n">Int</span><span class="p">.</span><span class="n">toString</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"></span>\r
67<span class="w"> </span><span class="s">&quot; is not a valid\</span>\r
68<span class="s"> \ digit in base &quot;</span><span class="p">,</span><span class="w"></span>\r
69<span class="w"> </span><span class="n">Int</span><span class="p">.</span><span class="n">toString</span><span class="w"> </span><span class="n">iBase</span><span class="p">])),</span><span class="w"></span>\r
70<span class="w"> </span><span class="n">fst</span><span class="p">)</span><span class="w"></span>\r
71<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
72\r
73<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">?</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">make</span><span class="w"> </span><span class="p">(</span><span class="k">op</span><span class="w"> </span><span class="n">*</span><span class="p">,</span><span class="w"> </span><span class="k">op</span><span class="w"> </span><span class="n">+</span><span class="p">,</span><span class="w"> </span><span class="n">id</span><span class="p">)</span><span class="w"> </span><span class="n">?</span><span class="w"></span>\r
74<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">II</span><span class="w"> </span><span class="n">?</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">make</span><span class="w"> </span><span class="p">(</span><span class="k">op</span><span class="w"> </span><span class="n">*</span><span class="p">,</span><span class="w"> </span><span class="k">op</span><span class="w"> </span><span class="n">+</span><span class="p">,</span><span class="w"> </span><span class="n">IntInf</span><span class="p">.</span><span class="n">fromInt</span><span class="p">)</span><span class="w"> </span><span class="n">?</span><span class="w"></span>\r
75<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="n">?</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">make</span><span class="w"> </span><span class="p">(</span><span class="k">op</span><span class="w"> </span><span class="n">*</span><span class="p">,</span><span class="w"> </span><span class="k">op</span><span class="w"> </span><span class="n">+</span><span class="p">,</span><span class="w"> </span><span class="n">Word</span><span class="p">.</span><span class="n">fromInt</span><span class="p">)</span><span class="w"> </span><span class="n">?</span><span class="w"></span>\r
76\r
77<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">`</span><span class="w"> </span><span class="n">?</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Fold</span><span class="p">.</span><span class="n">step1</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">step</span><span class="p">))</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"></span>\r
78<span class="w"> </span><span class="p">(</span><span class="n">step</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">),</span><span class="w"> </span><span class="n">step</span><span class="p">))</span><span class="w"> </span><span class="n">?</span><span class="w"></span>\r
79\r
80<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">10</span><span class="w"></span>\r
81<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">11</span><span class="w"></span>\r
82<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">12</span><span class="w"></span>\r
83<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">13</span><span class="w"></span>\r
84<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">14</span><span class="w"></span>\r
85<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">15</span><span class="w"></span>\r
86<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
87</pre></div></div></div>\r
88<div class="paragraph"><p>where</p></div>\r
89<div class="listingblock">\r
90<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">fst</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="p">_)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
91</pre></div></div></div>\r
92<div class="paragraph"><p>The idea is for the fold to start with zero and to construct the\r
93result one digit at a time, with each stepper multiplying the previous\r
94result by the base and adding the next digit. The code is abstracted\r
95in two different ways for extra generality. First, the <span class="monospaced">make</span>\r
96function abstracts over the various primitive operations (addition,\r
97multiplication, etc) that are needed to construct a number. This\r
98allows the same code to be shared for constants <span class="monospaced">I</span>, <span class="monospaced">II</span>, <span class="monospaced">W</span> used to\r
99write down the various numeric types. It also allows users to add new\r
100constants for additional numeric types, by supplying the necessary\r
101arguments to make.</p></div>\r
102<div class="paragraph"><p>Second, the step function, <span class="monospaced">&grave;</span>, is abstracted over the actual\r
103construction operation, which is created by make, and passed along the\r
104fold. This allows the same constant, <span class="monospaced">&grave;</span>, to be used for all\r
105numeric types. The alternative approach, having a different step\r
106function for each numeric type, would be more painful to use.</p></div>\r
107<div class="paragraph"><p>On the surface, it appears that the code checks the digits dynamically\r
108to ensure they are valid for the base. However, MLton will simplify\r
109everything away at compile time, leaving just the final numeric\r
110constant.</p></div>\r
111</div>\r
112</div>\r
113</div>\r
114<div id="footnotes"><hr></div>\r
115<div id="footer">\r
116<div id="footer-text">\r
117</div>\r
118<div id="footer-badges">\r
119</div>\r
120</div>\r
121</body>\r
122</html>\r