hl/static/report/haskell2010/haskellch4.html
2014-03-15 03:18:15 +01:00

6002 lines
278 KiB
HTML

<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd-->
<html xmlns="http://www.w3.org/1999/xhtml"
>
<head><title>4 Declarations and Bindings</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="generator" content="TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/)" />
<meta name="originator" content="TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/)" />
<!-- 2,html,xhtml -->
<meta name="src" content="haskell.tex" />
<meta name="date" content="2010-07-20 13:11:00" />
<link rel="stylesheet" type="text/css" href="haskell.css" />
</head><body
>
<!--l. 7--><div class="crosslinks"><p class="noindent">[<a
href="haskellch5.html" >next</a>] [<a
href="haskellch3.html" >prev</a>] [<a
href="haskellch3.html#tailhaskellch3.html" >prev-tail</a>] [<a
href="#tailhaskellch4.html">tail</a>] [<a
href="haskellpa1.html#haskellch4.html" >up</a>] </p></div>
<h2 class="chapterHead"><span class="titlemark">Chapter&#x00A0;4</span><br /><a
id="x10-620004"></a>Declarations and Bindings</h2> <a
id="dx10-62001"></a><a
id="dx10-62002"></a>
<p class="noindent"> In this chapter, we describe the syntax and informal semantics of Haskell <span
class="ptmri7t-">declarations</span>.
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-59" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-59-1g"><col
id="TBL-59-1" /><col
id="TBL-59-2" /><col
id="TBL-59-3" /><col
id="TBL-59-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-59-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-1-1"
class="td11"> <span
class="cmmi-10">module </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-1-3"
class="td11"> <span
class="pcrr7t-">module</span><span
class="cmmi-10">&#x00A0;modid</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">exports</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;body </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-2-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-2-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-2-3"
class="td11"> <span
class="cmmi-10">body </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-3-1"
class="td11"> <span
class="cmmi-10">body </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-3-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-3-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;impdecls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;topdecls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-4-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-4-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-4-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;impdecls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-5-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-5-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-5-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;topdecls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-6-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-59-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-7-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-8-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-8-1"
class="td11"> <span
class="cmmi-10">topdecls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-8-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-8-3"
class="td11"> <span
class="cmmi-10">topdecl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;topdecl</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-8-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-9-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-9-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-9-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-9-3"
class="td11"> <span
class="pcrr7t-">type</span><span
class="cmmi-10">&#x00A0;simpletype</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;type </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-10-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-10-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-10-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-10-3"
class="td11"> <span
class="pcrr7t-">data</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">context</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;simpletype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;constrs</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">deriving</span><span
class="cmr-10">]</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-11-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-11-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-11-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-11-3"
class="td11"> <span
class="pcrr7t-">newtype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">context</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;simpletype</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;newconstr</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">deriving</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-12-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-12-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-12-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-12-3"
class="td11"> <span
class="pcrr7t-">class</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">scontext</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;tycls</span><span
class="cmmi-10">&#x00A0;tyvar</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;cdecls</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-13-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-13-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-13-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-13-3"
class="td11"> <span
class="pcrr7t-">instance</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">scontext</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;qtycls</span><span
class="cmmi-10">&#x00A0;inst</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;idecls</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-14-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-14-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-14-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-14-3"
class="td11"> <span
class="pcrr7t-">default</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">(</span><span
class="cmmi-10">type</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;type</span><sub><span
class="cmmi-7">n</span></sub><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-14-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0; </span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-15-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-15-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-15-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-15-3"
class="td11"> <span
class="pcrr7t-">foreign</span><span
class="cmmi-10">&#x00A0;fdecl </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-16-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-16-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-16-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-16-3"
class="td11"> <span
class="cmmi-10">decl </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-17-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-17-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-59-18-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-18-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-19-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-19-1"
class="td11"> <span
class="cmmi-10">decls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-19-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-19-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;decl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;decl</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-19-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-20-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-20-1"
class="td11"> <span
class="cmmi-10">decl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-20-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-20-3"
class="td11"> <span
class="cmmi-10">gendecl </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-21-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-21-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-21-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-21-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">pat</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;rhs</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-22-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-22-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-23-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-23-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-24-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-24-1"
class="td11"> <span
class="cmmi-10">cdecls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-24-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-24-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;cdecl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;cdecl</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-24-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-25-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-25-1"
class="td11"> <span
class="cmmi-10">cdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-25-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-25-3"
class="td11"> <span
class="cmmi-10">gendecl </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-26-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-26-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-26-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-26-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;var</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;rhs </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-27-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-27-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-28-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-28-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-29-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-29-1"
class="td11"> <span
class="cmmi-10">idecls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-29-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-29-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;idecl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;idecl</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-29-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-30-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-30-1"
class="td11"> <span
class="cmmi-10">idecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-30-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-30-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;var</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;rhs </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-31-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-31-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-31-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-31-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-31-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>empty<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-32-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-32-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-33-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-33-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-34-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-34-1"
class="td11"> <span
class="cmmi-10">gendecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-34-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-34-3"
class="td11"> <span
class="cmmi-10">vars</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">context</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;type </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-59-34-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>type&#x00A0;signature<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-35-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-35-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-35-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-35-3"
class="td11"> <span
class="cmmi-10">fixity</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">integer</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;ops </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-59-35-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>fixity&#x00A0;declaration<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-36-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-36-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-59-36-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-36-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-36-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>empty&#x00A0;declaration<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-37-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-37-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-38-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-38-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-39-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-39-1"
class="td11"> <span
class="cmmi-10">ops </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-39-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-39-3"
class="td11"> <span
class="cmmi-10">op</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;op</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-39-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-40-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-40-1"
class="td11"> <span
class="cmmi-10">vars </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-40-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-40-3"
class="td11"> <span
class="cmmi-10">var</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;var</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-40-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-59-41-"><td style="white-space:nowrap; text-align:left;" id="TBL-59-41-1"
class="td11"> <span
class="cmmi-10">fixity </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-59-41-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-59-41-3"
class="td11"> <span
class="pcrr7t-">infixl</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">infixr</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">infix</span> </td>
</tr></table></div></div>
<a
id="dx10-62003"></a>
<a
id="dx10-62004"></a>
<a
id="dx10-62005"></a>
<a
id="dx10-62006"></a>
<a
id="dx10-62007"></a>
<a
id="dx10-62008"></a>
<a
id="dx10-62009"></a>
<a
id="dx10-62010"></a>
<a
id="dx10-62011"></a>
<a
id="dx10-62012"></a>
<a
id="dx10-62013"></a>
<a
id="dx10-62014"></a>
<a
id="dx10-62015"></a>
<p class="noindent"> The declarations in the syntactic category <span
class="cmmi-10">topdecls</span> are only allowed at the top level of a Haskell module (see
Chapter&#x00A0;<a
href="haskellch5.html#x11-980005">5<!--tex4ht:ref: modules --></a>), whereas <span
class="cmmi-10">decls</span> may be used either at the top level or in nested scopes (i.e.&#x00A0;those within a <span
class="pcrr7t-">let</span> or <span
class="pcrr7t-">where</span>
construct).
<p class="noindent"> For exposition, we divide the declarations into three groups: user-defined datatypes, consisting of <span
class="pcrr7t-">type</span>, <span
class="pcrr7t-">newtype</span>,
and <span
class="pcrr7t-">data</span> declarations (Section&#x00A0;<a
href="#x10-680004.2">4.2<!--tex4ht:ref: user-defined-datatypes --></a>); type classes and overloading, consisting of <span
class="pcrr7t-">class</span>, <span
class="pcrr7t-">instance</span>, and
<span
class="pcrr7t-">default</span> declarations (Section&#x00A0;<a
href="#x10-750004.3">4.3<!--tex4ht:ref: overloading --></a>); and nested declarations, consisting of value bindings, type signatures, and
fixity declarations (Section&#x00A0;<a
href="#x10-800004.4">4.4<!--tex4ht:ref: nested --></a>).
<p class="noindent"> Haskell has several primitive datatypes that are &#8220;hard-wired&#8221; (such as integers and floating-point numbers), but most
&#8220;built-in&#8221; datatypes are defined with normal Haskell code, using normal <span
class="pcrr7t-">type</span> and <span
class="pcrr7t-">data</span> declarations. These
&#8220;built-in&#8221; datatypes are described in detail in Section&#x00A0;<a
href="haskellch6.html#x13-1170006.1">6.1<!--tex4ht:ref: basic-types --></a>.
<h3 class="sectionHead"><span class="titlemark">4.1 </span> <a
id="x10-630004.1"></a>Overview of Types and Classes</h3>
<p class="noindent"> Haskell uses a traditional Hindley-Milner<a
id="dx10-63001"></a> polymorphic type system to provide a static type semantics <span class="cite">[<a
href="haskellli3.html#Xdamas-milner82">4</a>,&#x00A0;<a
href="haskellli3.html#Xhindley69">6</a>]</span>, but the
type system has been extended with <span
class="ptmri7t-">type classes </span>(or just <span
class="ptmri7t-">classes</span><a
id="dx10-63002"></a>) that provide a structured way to introduce
<span
class="ptmri7t-">overloaded </span>functions.<a
id="dx10-63003"></a> <a
id="dx10-63004"></a><a
id="dx10-63005"></a>
<p class="noindent"> A <span
class="pcrr7t-">class</span> declaration (Section&#x00A0;<a
href="#x10-760004.3.1">4.3.1<!--tex4ht:ref: class-decls --></a>) introduces a new <span
class="ptmri7t-">type class </span>and the overloaded operations that must be
supported by any type that is an instance of that class. An <span
class="pcrr7t-">instance</span> declaration (Section&#x00A0;<a
href="#x10-770004.3.2">4.3.2<!--tex4ht:ref: instance-decls --></a>) declares that a type
is an <span
class="ptmri7t-">instance </span>of a class and includes the definitions of the overloaded operations&#8212;called <span
class="ptmri7t-">class methods</span>&#8212;instantiated
on the named type. <a
id="dx10-63006"></a>
<p class="noindent"> For example, suppose we wish to overload the operations <span
class="pcrr7t-">(+)</span> and <span
class="pcrr7t-">negate</span> on types <span
class="pcrr7t-">Int</span> and <span
class="pcrr7t-">Float</span>. We
introduce a new type class called <span
class="pcrr7t-">Num</span>:
<p class="noindent">
<div class="quote">
<div class="verbatim" id="verbatim-25">
&#x00A0;&#x00A0;class&#x00A0;Num&#x00A0;a&#x00A0;&#x00A0;where&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;simplified&#x00A0;class&#x00A0;declaration&#x00A0;for&#x00A0;Num
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;(+)&#x00A0;&#x00A0;&#x00A0;&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;(Num&#x00A0;is&#x00A0;defined&#x00A0;in&#x00A0;the&#x00A0;Prelude)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;negate&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a
</div>
<p class="noindent"></div>
<p class="noindent"> This declaration may be read &#8220;a type <span
class="pcrr7t-">a</span> is an instance of the class <span
class="pcrr7t-">Num</span> if there are class methods <span
class="pcrr7t-">(+)</span> and <span
class="pcrr7t-">negate</span>,
of the given types, defined on it.&#8221;
<p class="noindent"> We may then declare <span
class="pcrr7t-">Int</span> and <span
class="pcrr7t-">Float</span> to be instances of this class:
<div class="quote">
<div class="verbatim" id="verbatim-26">
&#x00A0;&#x00A0;instance&#x00A0;Num&#x00A0;Int&#x00A0;&#x00A0;where&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;simplified&#x00A0;instance&#x00A0;of&#x00A0;Num&#x00A0;Int
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;x&#x00A0;+&#x00A0;y&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;=&#x00A0;&#x00A0;addInt&#x00A0;x&#x00A0;y
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;negate&#x00A0;x&#x00A0;&#x00A0;&#x00A0;&#x00A0;=&#x00A0;&#x00A0;negateInt&#x00A0;x
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;instance&#x00A0;Num&#x00A0;Float&#x00A0;&#x00A0;where&#x00A0;&#x00A0;&#x00A0;--&#x00A0;simplified&#x00A0;instance&#x00A0;of&#x00A0;Num&#x00A0;Float
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;x&#x00A0;+&#x00A0;y&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;=&#x00A0;&#x00A0;addFloat&#x00A0;x&#x00A0;y
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;negate&#x00A0;x&#x00A0;&#x00A0;&#x00A0;&#x00A0;=&#x00A0;&#x00A0;negateFloat&#x00A0;x
</div>
<p class="noindent"></div>
<p class="noindent"> where <span
class="pcrr7t-">addInt</span>, <span
class="pcrr7t-">negateInt</span>, <span
class="pcrr7t-">addFloat</span>, and <span
class="pcrr7t-">negateFloat</span> are assumed in this case to be primitive
functions, but in general could be any user-defined function. The first declaration above may be read
&#8220;<span
class="pcrr7t-">Int</span> is an instance of the class <span
class="pcrr7t-">Num</span> as witnessed by these definitions (i.e.&#x00A0;class methods)<a
id="dx10-63007"></a> for <span
class="pcrr7t-">(+)</span> and
<span
class="pcrr7t-">negate</span>.&#8221;
<p class="noindent"> More examples of type classes can be found in the papers by Jones <span class="cite">[<a
href="haskellli3.html#Xjones:cclasses">8</a>]</span> or Wadler and Blott <span class="cite">[<a
href="haskellli3.html#Xwadler:classes">13</a>]</span>. The term &#8216;type
class&#8217; was used to describe the original Haskell 1.0 type system; &#8216;constructor class&#8217; was used to describe an extension
to the original type classes. There is no longer any reason to use two different terms: in this report,
&#8216;type class&#8217; includes both the original Haskell type classes and the constructor classes introduced by
Jones.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.1.1 </span> <a
id="x10-640004.1.1"></a>Kinds</h4>
<p class="noindent"> To ensure that they are valid, type expressions are classified into different <span
class="ptmri7t-">kinds</span>, <a
id="dx10-64001"></a>which take one of two possible
forms:
<ul class="itemize1">
<li class="itemize">The symbol <span
class="cmsy-10">&lowast; </span>represents the kind of all nullary type constructors.
</li>
<li class="itemize">If <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub> and <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">2</span></sub> are kinds, then <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub> <span
class="cmsy-10">&rarr; </span><span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">2</span></sub> is the kind of types that take a type of kind <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub> and return a type
of kind <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">2</span></sub>.</li></ul>
<p class="noindent"> Kind inference checks the validity of type expressions in a similar way that type inference checks the validity of
value expressions. However, unlike types, kinds are entirely implicit and are not a visible part of the language. Kind
inference is discussed in Section&#x00A0;<a
href="#x10-970004.6">4.6<!--tex4ht:ref: kindinference --></a>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.1.2 </span> <a
id="x10-650004.1.2"></a>Syntax of Types</h4>
<a
id="dx10-65001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-60" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-60-1g"><col
id="TBL-60-1" /><col
id="TBL-60-2" /><col
id="TBL-60-3" /><col
id="TBL-60-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-60-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-1-1"
class="td11"> <span
class="cmmi-10">type </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-60-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-1-3"
class="td11"> <span
class="cmmi-10">btype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">-&#x003E;</span><span
class="cmmi-10">&#x00A0;type</span><span
class="cmr-10">] </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-60-1-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>function&#x00A0;type<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-2-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-60-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-3-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-4-1"
class="td11"> <span
class="cmmi-10">btype </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-60-4-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-4-3"
class="td11"> <span
class="cmr-10">[</span><span
class="cmmi-10">btype</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;atype </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-60-4-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>type&#x00A0;application<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-5-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-60-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-6-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-7-1"
class="td11"> <span
class="cmmi-10">atype </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-60-7-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-7-3"
class="td11"> <span
class="cmmi-10">gtycon </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-8-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-8-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-8-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-8-3"
class="td11"> <span
class="cmmi-10">tyvar </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-9-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-9-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-9-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-9-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;type</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;type</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-9-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>tuple&#x00A0;type<span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">2) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-10-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-10-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-10-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-10-3"
class="td11"> <span
class="pcrr7t-">[</span><span
class="cmmi-10">&#x00A0;type</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">]</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-10-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>list&#x00A0;type<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-11-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-11-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-11-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-11-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;type</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-11-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>parenthesised&#x00A0;constructor<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-12-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-12-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-13-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-13-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-14-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-14-1"
class="td11"> <span
class="cmmi-10">gtycon </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-60-14-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-14-3"
class="td11"> <span
class="cmmi-10">qtycon </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-15-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-15-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-15-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-15-3"
class="td11"> <span
class="pcrr7t-">()</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-15-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>unit&#x00A0;type<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-16-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-16-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-16-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-16-3"
class="td11"> <span
class="pcrr7t-">[]</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-16-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>list&#x00A0;constructor<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-17-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-17-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-17-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-17-3"
class="td11"> <span
class="pcrr7t-">(-&#x003E;)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-17-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>function&#x00A0;constructor<span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-60-18-"><td style="white-space:nowrap; text-align:left;" id="TBL-60-18-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-60-18-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-18-3"
class="td11"> <span
class="pcrr7t-">(,</span><span
class="cmsy-10">{</span><span
class="pcrr7t-">,</span><span
class="cmsy-10">}</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-60-18-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>tupling&#x00A0;constructors<span
class="cmr-10">) </span></td>
</tr></table></div></div>
<a
id="dx10-65002"></a>
<a
id="dx10-65003"></a>
<a
id="dx10-65004"></a>
<a
id="dx10-65005"></a>
<p class="noindent"> The syntax for Haskell type expressions <a
id="dx10-65006"></a><a
id="dx10-65007"></a> is given above. Just as data values are built using data constructors, type
values are built from <span
class="cmmi-10">type</span><span
class="cmmi-10">&#x00A0;constructors</span>. As with data constructors, the names of type constructors start
with uppercase letters. Unlike data constructors, infix type constructors are not allowed (other than
<span
class="pcrr7t-">(-&#x003E;)</span>).
<p class="noindent"> The main forms of type expression are as follows:
<ol class="enumerate1" >
<li
class="enumerate" id="x10-65009x1">Type variables, written as identifiers beginning with a lowercase letter. The kind of a variable is
determined implicitly by the context in which it appears.
</li>
<li
class="enumerate" id="x10-65011x2">Type constructors. Most type constructors are written as an identifier beginning with an uppercase letter. For
example:
<ul class="itemize1">
<li class="itemize"><span
class="pcrr7t-">Char</span>, <span
class="pcrr7t-">Int</span>, <span
class="pcrr7t-">Integer</span>, <span
class="pcrr7t-">Float</span>, <span
class="pcrr7t-">Double</span> and <span
class="pcrr7t-">Bool</span> are type constants with kind <span
class="cmsy-10">&lowast;</span>.
</li>
<li class="itemize"><span
class="pcrr7t-">Maybe</span> and <span
class="pcrr7t-">IO</span> are unary type constructors, and treated as types with kind <span
class="cmsy-10">&lowast;&rarr;&lowast;</span>.
</li>
<li class="itemize">The declarations <span
class="pcrr7t-">data</span><span
class="pcrr7t-">&#x00A0;T</span><span
class="pcrr7t-">&#x00A0;...</span> or <span
class="pcrr7t-">newtype</span><span
class="pcrr7t-">&#x00A0;T</span><span
class="pcrr7t-">&#x00A0;...</span> add the type constructor <span
class="pcrr7t-">T</span> to the type
vocabulary. The kind of <span
class="pcrr7t-">T</span> is determined by kind inference.</li></ul>
<p class="noindent"> Special syntax is provided for certain built-in type constructors:
<ul class="itemize1">
<li class="itemize">The <span
class="ptmri7t-">trivial type</span><a
id="dx10-65012"></a> is written as <span
class="pcrr7t-">()</span> and has kind <span
class="cmsy-10">&lowast;</span>. It denotes the &#8220;nullary tuple&#8221; type, and has exactly
one value, also written <span
class="pcrr7t-">()</span> (see Sections&#x00A0;<a
href="haskellch3.html#x8-380003.9">3.9<!--tex4ht:ref: unit-expression --></a> and&#x00A0;<a
href="haskellch6.html#x13-1220006.1.5">6.1.5<!--tex4ht:ref: basic-trivial --></a>).
</li>
<li class="itemize">The <span
class="ptmri7t-">function type </span>is written as <span
class="pcrr7t-">(-&#x003E;)</span> and has<a
id="dx10-65013"></a> kind <span
class="cmsy-10">&lowast;&rarr;&lowast;&rarr;&lowast;</span>.
</li>
<li class="itemize">The <span
class="ptmri7t-">list type </span>is written as <span
class="pcrr7t-">[]</span> and has kind <span
class="cmsy-10">&lowast;&rarr;&lowast;</span>.<a
id="dx10-65014"></a>
</li>
<li class="itemize">The <span
class="ptmri7t-">tuple types </span>are written as <span
class="pcrr7t-">(,)</span>,<a
id="dx10-65015"></a> <span
class="pcrr7t-">(,,)</span>, and so on. Their kinds are <span
class="cmsy-10">&lowast;&rarr;&lowast;&rarr;&lowast;</span>, <span
class="cmsy-10">&lowast;&rarr;&lowast;&rarr;&lowast;&rarr;</span>
<span
class="cmsy-10">&lowast;</span>, and so on.</li></ul>
<p class="noindent"> Use of the <span
class="pcrr7t-">(-&#x003E;)</span> and <span
class="pcrr7t-">[]</span> constants is described in more detail below.
</li>
<li
class="enumerate" id="x10-65017x3">Type application. If <span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub> is a type of kind <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub> <span
class="cmsy-10">&rarr; </span><span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">2</span></sub> and <span
class="cmmi-10">t</span><sub><span
class="cmr-7">2</span></sub> is a type of kind <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub>, then <span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">2</span></sub> is a type expression of
kind <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">2</span></sub>.
</li>
<li
class="enumerate" id="x10-65019x4">A <span
class="ptmri7t-">parenthesized type</span>, having form <span
class="pcrr7t-">(</span><span
class="cmmi-10">t</span><span
class="pcrr7t-">)</span>, is identical to the type <span
class="cmmi-10">t</span>.
</li></ol>
<p class="noindent"> For example, the type expression <span
class="pcrr7t-">IO</span><span
class="pcrr7t-">&#x00A0;a</span> can be understood as the application of a constant, <span
class="pcrr7t-">IO</span>, to the variable <span
class="pcrr7t-">a</span>.
Since the <span
class="pcrr7t-">IO</span> type constructor has kind <span
class="cmsy-10">&lowast;&rarr;&lowast;</span>, it follows that both the variable <span
class="pcrr7t-">a</span> and the whole expression, <span
class="pcrr7t-">IO</span><span
class="pcrr7t-">&#x00A0;a</span>,
must have kind <span
class="cmsy-10">&lowast;</span>. In general, a process of <span
class="ptmri7t-">kind inference</span><a
id="dx10-65020"></a><a
id="dx10-65021"></a> (see Section&#x00A0;<a
href="#x10-970004.6">4.6<!--tex4ht:ref: kindinference --></a>) is needed to determine appropriate kinds
for user-defined datatypes, type synonyms, and classes.
<p class="noindent"> Special syntax is provided to allow certain type expressions to be written in a more traditional style:
<ol class="enumerate1" >
<li
class="enumerate" id="x10-65023x1">A <span
class="ptmri7t-">function type</span><a
id="dx10-65024"></a> has the form <span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">-&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">2</span></sub>, which is equivalent to the type <span
class="pcrr7t-">(-&#x003E;)</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">2</span></sub>.
Function arrows associate to the right. For example, <span
class="pcrr7t-">Int</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;Int</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;Float</span> means
<span
class="pcrr7t-">Int</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;(Int</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;Float)</span>.
</li>
<li
class="enumerate" id="x10-65026x2">A <span
class="ptmri7t-">tuple type</span><a
id="dx10-65027"></a> has the form <span
class="pcrr7t-">(</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">k</span></sub><span
class="pcrr7t-">)</span> where <span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">2</span>, which is equivalent to the type
<span
class="pcrr7t-">(,</span>&hellip;<span
class="pcrr7t-">,)</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">k</span></sub> where there are <span
class="cmmi-10">k</span><span
class="cmsy-10">&minus;</span><span
class="cmr-10">1 </span>commas between the parenthesis. It denotes the type of <span
class="cmmi-10">k</span>-tuples
with the first component of type <span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub>, the second component of type <span
class="cmmi-10">t</span><sub><span
class="cmr-7">2</span></sub>, and so on (see Sections&#x00A0;<a
href="haskellch3.html#x8-360003.8">3.8<!--tex4ht:ref: tuples --></a> and
<a
href="haskellch6.html#x13-1210006.1.4">6.1.4<!--tex4ht:ref: basic-tuples --></a>).
</li>
<li
class="enumerate" id="x10-65029x3">A <span
class="ptmri7t-">list type</span><a
id="dx10-65030"></a> has the form <span
class="pcrr7t-">[</span><span
class="cmmi-10">t</span><span
class="pcrr7t-">]</span>, which is equivalent to the type <span
class="pcrr7t-">[]</span><span
class="cmmi-10">&#x00A0;t</span>. It denotes the type of lists with
elements of type <span
class="cmmi-10">t</span> (see Sections&#x00A0;<a
href="haskellch3.html#x8-340003.7">3.7<!--tex4ht:ref: lists --></a> and <a
href="haskellch6.html#x13-1200006.1.3">6.1.3<!--tex4ht:ref: basic-lists --></a>).
</li></ol>
<p class="noindent"> These special syntactic forms always denote the built-in type constructors for functions, tuples, and lists, regardless
of what is in scope. In a similar way, the prefix type constructors <span
class="pcrr7t-">(-&#x003E;)</span>, <span
class="pcrr7t-">[]</span>, <span
class="pcrr7t-">()</span>, <span
class="pcrr7t-">(,)</span>, and so on, always denote the
built-in type constructors; they cannot be qualified, nor mentioned in import or export lists (Chapter&#x00A0;<a
href="haskellch5.html#x11-980005">5<!--tex4ht:ref: modules --></a>). (Hence the
special production, &#8220;gtycon&#8221;, above.)
<p class="noindent"> Although the list and tuple types have special syntax, their semantics is the same as the equivalent user-defined
algebraic data types.
<p class="noindent"> Notice that expressions and types have a consistent syntax. If <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub> is the type of expression or pattern <span
class="cmmi-10">e</span><sub><span
class="cmmi-7">i</span></sub>, then
the expressions <span
class="pcrr7t-">(\</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">-&#x003E;</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmr-7">2</span></sub><span
class="pcrr7t-">)</span>, <span
class="pcrr7t-">[</span><span
class="cmmi-10">e</span><sub><span
class="cmr-7">1</span></sub><span
class="pcrr7t-">]</span>, and <span
class="pcrr7t-">(</span><span
class="cmmi-10">e</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,e</span><sub><span
class="cmr-7">2</span></sub><span
class="pcrr7t-">)</span> have the types <span
class="pcrr7t-">(</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">-&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">2</span></sub><span
class="pcrr7t-">)</span>, <span
class="pcrr7t-">[</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="pcrr7t-">]</span>, and <span
class="pcrr7t-">(</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,t</span><sub><span
class="cmr-7">2</span></sub><span
class="pcrr7t-">)</span>,
respectively.
<a
id="dx10-65031"></a>
<p class="noindent"> With one exception (that of the distinguished type variable in a class declaration (Section&#x00A0;<a
href="#x10-760004.3.1">4.3.1<!--tex4ht:ref: class-decls --></a>)), the type variables
in a Haskell type expression are all assumed to be universally quantified; there is no explicit syntax for universal
quantification&#x00A0;<span class="cite">[<a
href="haskellli3.html#Xdamas-milner82">4</a>]</span>. For example, the type expression <span
class="pcrr7t-">a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span> denotes the type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span>. For clarity, however,
we often write quantification explicitly when discussing the types of Haskell programs. When we write an explicitly
quantified type, the scope of the <span
class="cmsy-10">&forall;</span> extends as far to the right as possible; for example, <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span> means
<span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmr-10">)</span>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.1.3 </span> <a
id="x10-660004.1.3"></a>Syntax of Class Assertions and Contexts</h4>
<a
id="dx10-66001"></a>
<a
id="dx10-66002"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-61" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-61-1g"><col
id="TBL-61-1" /><col
id="TBL-61-2" /><col
id="TBL-61-3" /><col
id="TBL-61-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-61-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-1-1"
class="td11"> <span
class="cmmi-10">context </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-61-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-1-3"
class="td11"> <span
class="cmmi-10">class </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-61-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-2-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-61-2-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-2-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;class</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;class</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-2-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-61-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-3-1"
class="td11"> <span
class="cmmi-10">class </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-61-3-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-3-3"
class="td11"> <span
class="cmmi-10">qtycls</span><span
class="cmmi-10">&#x00A0;tyvar </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-61-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-4-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-61-4-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-4-3"
class="td11"> <span
class="cmmi-10">qtycls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;tyvar</span><span
class="cmmi-10">&#x00A0;atype</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;atype</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-4-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-61-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-5-1"
class="td11"> <span
class="cmmi-10">qtycls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-61-5-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-5-3"
class="td11"> <span
class="cmr-10">[</span><span
class="cmmi-10">&#x00A0;modid</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;tycls </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-61-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-6-1"
class="td11"> <span
class="cmmi-10">tycls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-61-6-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-6-3"
class="td11"> <span
class="cmmi-10">conid </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-61-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-61-7-1"
class="td11"> <span
class="cmmi-10">tyvar </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-61-7-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-61-7-3"
class="td11"> <span
class="cmmi-10">varid </span></td>
</tr></table></div></div>
<a
id="dx10-66003"></a>
<a
id="dx10-66004"></a>
<a
id="dx10-66005"></a>
<a
id="dx10-66006"></a>
<a
id="dx10-66007"></a>
<p class="noindent"> A <span
class="ptmri7t-">class assertion </span>has form <span
class="cmmi-10">qtycls</span><span
class="cmmi-10">&#x00A0;tyvar</span>, and indicates the membership of the type <span
class="cmmi-10">tyvar</span> in the class <span
class="cmmi-10">qtycls</span>. A
class identifier begins with an uppercase letter. A <span
class="ptmri7t-">context </span>consists of zero or more class assertions, and has the general
form
<span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;C</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;C</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span>
where <span
class="cmmi-10">C</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;C</span><sub><span
class="cmmi-7">n</span></sub> are class identifiers, and each of the <span
class="cmmi-10">u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">n</span></sub> is either a type variable, or the
application of type variable to one or more types. The outer parentheses may be omitted when <span
class="cmmi-10">n </span><span
class="cmr-10">= 1</span>.
In general, we use <span
class="cmmi-10">cx</span> to denote a context and we write <span
class="cmmi-10">cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span> to indicate the type <span
class="cmmi-10">t</span> restricted by
the context <span
class="cmmi-10">cx</span>. The context <span
class="cmmi-10">cx</span> must only contain type variables referenced in <span
class="cmmi-10">t</span>. For convenience, we
write <span
class="cmmi-10">cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span> even if the context <span
class="cmmi-10">cx</span> is empty, although in this case the concrete syntax contains no
<span
class="pcrr7t-">=&#x003E;</span>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.1.4 </span> <a
id="x10-670004.1.4"></a>Semantics of Types and Classes</h4>
<p class="noindent"> In this section, we provide informal details of the type system. (Wadler and Blott <span class="cite">[<a
href="haskellli3.html#Xwadler:classes">13</a>]</span> and Jones <span class="cite">[<a
href="haskellli3.html#Xjones:cclasses">8</a>]</span> discuss type and
constructor classes, respectively, in more detail.)
<p class="noindent"> The Haskell type system attributes a <span
class="ptmri7t-">type </span>to each <a
id="dx10-67001"></a>expression in the program. In general, a type is of the form
<span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span>, where <span class="overline"><span
class="cmmi-10">u</span></span> is a set of type variables <span
class="cmmi-10">u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">n</span></sub>. In any such type, any of the universally-quantified
type variables <span
class="cmmi-10">u</span><sub><span
class="cmmi-7">i</span></sub> that are free in <span
class="cmmi-10">cx</span> must also be free in <span
class="cmmi-10">t</span>. Furthermore, the context <span
class="cmmi-10">cx</span> must be of the form given
above in Section&#x00A0;<a
href="#x10-660004.1.3">4.1.3<!--tex4ht:ref: classes&contexts --></a>. For example, here are some valid types:
<div class="quote">
<div class="verbatim" id="verbatim-27">
&#x00A0;&#x00A0;Eq&#x00A0;a&#x00A0;=&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a
&#x00A0;<br />&#x00A0;&#x00A0;(Eq&#x00A0;a,&#x00A0;Show&#x00A0;a,&#x00A0;Eq&#x00A0;b)&#x00A0;=&#x003E;&#x00A0;[a]&#x00A0;-&#x003E;&#x00A0;[b]&#x00A0;-&#x003E;&#x00A0;String
&#x00A0;<br />&#x00A0;&#x00A0;(Eq&#x00A0;(f&#x00A0;a),&#x00A0;Functor&#x00A0;f)&#x00A0;=&#x003E;&#x00A0;(a&#x00A0;-&#x003E;&#x00A0;b)&#x00A0;-&#x003E;&#x00A0;f&#x00A0;a&#x00A0;-&#x003E;&#x00A0;f&#x00A0;b&#x00A0;-&#x003E;&#x00A0;Bool
</div>
<p class="noindent"></div>
<p class="noindent"> In the third type, the constraint <span
class="pcrr7t-">Eq</span><span
class="pcrr7t-">&#x00A0;(f</span><span
class="pcrr7t-">&#x00A0;a)</span> cannot be made simpler because <span
class="pcrr7t-">f</span> is universally quantified.
<p class="noindent"> The type of an expression <span
class="cmmi-10">e</span> depends on a <span
class="ptmri7t-">type environment</span><a
id="dx10-67002"></a> that gives types for the free variables in <span
class="cmmi-10">e</span>, and a <span
class="ptmri7t-">class</span>
<span
class="ptmri7t-">environment</span><a
id="dx10-67003"></a> that declares which types are instances of which classes (a type becomes an instance of a class only via
the presence of an <span
class="pcrr7t-">instance</span> declaration or a <span
class="pcrr7t-">deriving</span> clause).
<p class="noindent"> Types are related by a generalization preorder <a
id="dx10-67004"></a>(specified below); the most general type, up to the equivalence
induced by the generalization preorder, that can be assigned to a particular expression (in a given environment) is
called its <span
class="ptmri7t-">principal type</span>. <a
id="dx10-67005"></a>Haskell&#8217;s extended Hindley-Milner type system can infer the principal type of all
expressions, including the proper use of overloaded class methods (although certain ambiguous overloadings could
arise, as described in Section&#x00A0;<a
href="#x10-790004.3.4">4.3.4<!--tex4ht:ref: default-decls --></a>). Therefore, explicit typings (called <span
class="ptmri7t-">type signatures</span>) <a
id="dx10-67006"></a>are usually optional (see
Sections&#x00A0;<a
href="haskellch3.html#x8-560003.16">3.16<!--tex4ht:ref: expression-type-sigs --></a> and&#x00A0;<a
href="#x10-810004.4.1">4.4.1<!--tex4ht:ref: type-signatures --></a>).
<p class="noindent"> The type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">1</span></sub> is <span
class="ptmri7t-">more general than </span>the type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">w</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><sub><span
class="cmr-7">2</span></sub><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">2</span></sub> if and only if there is a substitution <span
class="cmmi-10">S</span>
whose domain is <span class="overline"><span
class="cmmi-10">u</span></span> such that:
<ul class="itemize1">
<li class="itemize"><span
class="cmmi-10">t</span><sub><span
class="cmr-7">2</span></sub> is identical to <span
class="cmmi-10">S</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmr-10">)</span>.
</li>
<li class="itemize">Whenever <span
class="cmmi-10">cx</span><sub><span
class="cmr-7">2</span></sub> holds in the class environment, <span
class="cmmi-10">S</span><span
class="cmr-10">(</span><span
class="cmmi-10">cx</span><sub><span
class="cmr-7">1</span></sub><span
class="cmr-10">)</span> also holds.</li></ul>
<p class="noindent"> A value of type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span>, may be instantiated at types <span class="overline"><span
class="cmmi-10">s</span></span> if and only if the context <span
class="cmmi-10">cx</span><span
class="cmr-10">[</span><span class="overline"><span
class="cmmi-10">s</span></span><span
class="cmmi-10">&#x2215;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmr-10">]</span> holds. For
example, consider the function <span
class="pcrr7t-">double</span>:
<div class="quote">
<div class="verbatim" id="verbatim-28">
&#x00A0;&#x00A0;double&#x00A0;x&#x00A0;=&#x00A0;x&#x00A0;+&#x00A0;x
</div>
<p class="noindent"></div>
<p class="noindent"> The most general type of <span
class="pcrr7t-">double</span> is <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Num</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span>. <span
class="pcrr7t-">double</span> may be applied to values of type <span
class="pcrr7t-">Int</span>
(instantiating <span
class="cmmi-10">a</span> to <span
class="pcrr7t-">Int</span>), since <span
class="pcrr7t-">Num</span><span
class="pcrr7t-">&#x00A0;Int</span> holds, because <span
class="pcrr7t-">Int</span> is an instance of the class <span
class="pcrr7t-">Num</span>. However, <span
class="pcrr7t-">double</span> may
not normally be applied to values of type <span
class="pcrr7t-">Char</span>, because <span
class="pcrr7t-">Char</span> is not normally an instance of class <span
class="pcrr7t-">Num</span>.
The user may choose to declare such an instance, in which case <span
class="pcrr7t-">double</span> may indeed be applied to a
<span
class="pcrr7t-">Char</span>.
<p class="noindent">
<h3 class="sectionHead"><span class="titlemark">4.2 </span> <a
id="x10-680004.2"></a>User-Defined Datatypes</h3>
<a
id="dx10-68001"></a>
<p class="noindent"> In this section, we describe algebraic datatypes (<span
class="pcrr7t-">data</span> declarations), renamed datatypes (<span
class="pcrr7t-">newtype</span>
declarations), and type synonyms (<span
class="pcrr7t-">type</span> declarations). These declarations may only appear at the top level of a
module.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.2.1 </span> <a
id="x10-690004.2.1"></a>Algebraic Datatype Declarations</h4>
<a
id="dx10-69001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-62" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-62-1g"><col
id="TBL-62-1" /><col
id="TBL-62-2" /><col
id="TBL-62-3" /><col
id="TBL-62-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-62-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-1-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-1-3"
class="td11"> <span
class="pcrr7t-">data</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">context</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;simpletype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;constrs</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">deriving</span><span
class="cmr-10">]</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-2-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-62-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-3-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-4-1"
class="td11"> <span
class="cmmi-10">simpletype </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-4-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-4-3"
class="td11"> <span
class="cmmi-10">tycon</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmmi-7">k</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-4-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-5-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-62-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-6-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-7-1"
class="td11"> <span
class="cmmi-10">constrs </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-7-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-7-3"
class="td11"> <span
class="cmmi-10">constr</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;constr</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-7-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-8-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-8-1"
class="td11"> <span
class="cmmi-10">constr </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-8-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-8-3"
class="td11"> <span
class="cmmi-10">con</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">!</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;atype</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">!</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;atype</span><sub><span
class="cmmi-7">k</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-8-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>arity<span
class="cmmi-10">&#x00A0;con</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmr-10">=</span> <span
class="cmmi-10">&#x00A0;k,</span><span
class="cmmi-10">&#x00A0;k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-9-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-9-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-62-9-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-9-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">btype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">!</span><span
class="cmmi-10">&#x00A0;atype</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;conop</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">btype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">!</span><span
class="cmmi-10">&#x00A0;atype</span><span
class="cmr-10">) </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-62-9-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>infix<span
class="cmmi-10">&#x00A0;conop</span><span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-10-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-10-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-62-10-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-10-3"
class="td11"> <span
class="cmmi-10">con</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;fielddecl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;fielddecl</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-10-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-11-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-11-1"
class="td11"> <span
class="cmmi-10">fielddecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-11-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-11-3"
class="td11"> <span
class="cmmi-10">vars</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">type</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">!</span><span
class="cmmi-10">&#x00A0;atype</span><span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-12-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-12-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-13-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-13-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-14-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-14-1"
class="td11"> <span
class="cmmi-10">deriving </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-14-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-14-3"
class="td11"> <span
class="pcrr7t-">deriving</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">dclass</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">(</span><span
class="cmmi-10">dclass</span><sub><span
class="cmr-7">1</span></sub><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;dclass</span><sub><span
class="cmmi-7">n</span></sub><span
class="pcrr7t-">)</span><span
class="cmr-10">) </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-62-14-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-62-15-"><td style="white-space:nowrap; text-align:left;" id="TBL-62-15-1"
class="td11"> <span
class="cmmi-10">dclass </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-62-15-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-62-15-3"
class="td11"> <span
class="cmmi-10">qtycls </span></td>
</tr></table></div></div>
<a
id="dx10-69002"></a>
<a
id="dx10-69003"></a>
<a
id="dx10-69004"></a>
<a
id="dx10-69005"></a>
<a
id="dx10-69006"></a>
<a
id="dx10-69007"></a>
<a
id="dx10-69008"></a>
<a
id="dx10-69009"></a>
<p class="noindent"> The precedence<a
id="dx10-69010"></a> for <span
class="cmmi-10">constr</span> is the same as that for expressions&#8212;normal constructor application has higher
precedence than infix constructor application (thus <span
class="pcrr7t-">a</span><span
class="pcrr7t-">&#x00A0;:</span><span
class="pcrr7t-">&#x00A0;Foo</span><span
class="pcrr7t-">&#x00A0;a</span> parses as <span
class="pcrr7t-">a</span><span
class="pcrr7t-">&#x00A0;:</span><span
class="pcrr7t-">&#x00A0;(Foo</span><span
class="pcrr7t-">&#x00A0;a)</span>).
<p class="noindent"> An algebraic datatype declaration has the form:
<span
class="pcrr7t-">data</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;K</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">11</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">1</span><span
class="cmmi-7">k</span><sub><span
class="cmr-5">1</span></sub></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><img
src="haskell0x.png" alt="&sdot;&sdot;&sdot;" class="cdots" /><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;K</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">n</span><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">nk</span><sub><span
class="cmmi-5">n</span></sub></sub>
where <span
class="cmmi-10">cx</span> is a context. This declaration introduces a new <span
class="ptmri7t-">type constructor</span> <span
class="cmmi-10">T</span> with zero or more constituent
<span
class="ptmri7t-">data constructors</span> <span
class="cmmi-10">K</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;K</span><sub><span
class="cmmi-7">n</span></sub>. <a
id="dx10-69011"></a><a
id="dx10-69012"></a> In this Report, the unqualified term &#8220;constructor&#8221; always means &#8220;data
constructor&#8221;.
<p class="noindent"> The types of the data constructors are given by:
<span
class="cmmi-10">K</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0; </span><span
class="cmr-10">::</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;cx</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">i</span><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><img
src="haskell1x.png" alt="&sdot;&sdot;&sdot;" class="cdots" /><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">ik</span><sub><span
class="cmmi-5">i</span></sub></sub><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmr-10">)</span>
where <span
class="cmmi-10">cx</span><sub><span
class="cmmi-7">i</span></sub> is the largest subset of <span
class="cmmi-10">cx</span> that constrains only those type variables free in the types <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">ik</span><sub><span
class="cmmi-5">i</span></sub></sub>. The type
variables <span
class="cmmi-10">u</span><sub><span
class="cmr-7">1</span></sub> through <span
class="cmmi-10">u</span><sub><span
class="cmmi-7">k</span></sub> must be distinct and may appear in <span
class="cmmi-10">cx</span> and the <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">ij</span></sub>; it is a static error for any other
type variable to appear in <span
class="cmmi-10">cx</span> or on the right-hand-side. The new type constant <span
class="cmmi-10">T</span> has a kind of the form
<span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub> <span
class="cmsy-10">&rarr;</span><span
class="cmmi-10">&hellip;</span> <span
class="cmsy-10">&rarr; </span><span
class="cmmi-10">&kappa;</span><sub><span
class="cmmi-7">k</span></sub> <span
class="cmsy-10">&rarr;&lowast; </span>where the kinds <span
class="cmmi-10">&kappa;</span><sub><span
class="cmmi-7">i</span></sub> of the argument variables <span
class="cmmi-10">u</span><sub><span
class="cmmi-7">i</span></sub> are determined by kind inference as described
in Section&#x00A0;<a
href="#x10-970004.6">4.6<!--tex4ht:ref: kindinference --></a><a
id="dx10-69013"></a><a
id="dx10-69014"></a>. This means that <span
class="cmmi-10">T</span> may be used in type expressions with anywhere between <span
class="cmr-10">0</span> and <span
class="cmmi-10">k</span>
arguments.
<p class="noindent"> For example, the declaration
<div class="quote">
<div class="verbatim" id="verbatim-29">
&#x00A0;&#x00A0;data&#x00A0;Eq&#x00A0;a&#x00A0;=&#x003E;&#x00A0;Set&#x00A0;a&#x00A0;=&#x00A0;NilSet&#x00A0;|&#x00A0;ConsSet&#x00A0;a&#x00A0;(Set&#x00A0;a)
</div>
<p class="noindent"></div>
<p class="noindent"> introduces a type constructor <span
class="pcrr7t-">Set</span> of kind <span
class="cmsy-10">&lowast;&rarr;&lowast;</span>, and constructors <span
class="pcrr7t-">NilSet</span> and <span
class="pcrr7t-">ConsSet</span> with types
<div class="array"> <table id="TBL-63" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-63-1g"><col
id="TBL-63-1" /><col
id="TBL-63-2" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">NilSet</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmr-10">::</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Set</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span> </div></td></tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">ConsSet</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmr-10">::</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Eq</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Set</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Set</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span></div></td>
</tr></table> </div>
In the example given, the overloaded type for <span
class="pcrr7t-">ConsSet</span> ensures that <span
class="pcrr7t-">ConsSet</span> can only be applied to values whose
type is an instance of the class <span
class="pcrr7t-">Eq</span>. Pattern matching against <span
class="pcrr7t-">ConsSet</span> also gives rise to an <span
class="pcrr7t-">Eq</span><span
class="pcrr7t-">&#x00A0;a</span> constraint. For
example:
<div class="quote">
<div class="verbatim" id="verbatim-30">
&#x00A0;&#x00A0;f&#x00A0;(ConsSet&#x00A0;a&#x00A0;s)&#x00A0;=&#x00A0;a
</div>
<p class="noindent"></div>
<p class="noindent"> the function <span
class="pcrr7t-">f</span> has inferred type <span
class="pcrr7t-">Eq</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;=&#x003E;</span><span
class="pcrr7t-">&#x00A0;Set</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span>. The context in the <span
class="pcrr7t-">data</span> declaration has no other effect
whatsoever.
<p class="noindent"> The visibility of a datatype&#8217;s constructors (i.e.&#x00A0;the &#8220;abstractness&#8221; <a
id="dx10-69015"></a>of the datatype) outside of the module in which the
datatype is defined is controlled by the form of the datatype&#8217;s name in the export list as described in
Section&#x00A0;<a
href="haskellch5.html#x11-1150005.8">5.8<!--tex4ht:ref: abstract-types --></a>.
<p class="noindent"> The optional <span
class="pcrr7t-">deriving</span> part of a <span
class="pcrr7t-">data</span> declaration has to do with <span
class="ptmri7t-">derived instances</span>, and is described in
Section&#x00A0;<a
href="#x10-780004.3.3">4.3.3<!--tex4ht:ref: derived-decls --></a>.
<p class="noindent"> <span class="paragraphHead"><a
id="x10-700004.2.1"></a><span
class="ptmb7t-">Labelled Fields</span></span>
<a
id="dx10-70001"></a>
A data constructor of arity <span
class="cmmi-10">k</span> creates an object with <span
class="cmmi-10">k</span> components. These components are normally accessed
positionally as arguments to the constructor in expressions or patterns. For large datatypes it is useful to assign
<span
class="cmmi-10">field</span><span
class="cmmi-10">&#x00A0;labels</span> to the components of a data object. This allows a specific field to be referenced independently of its
location within the constructor.
<p class="noindent"> A constructor definition in a <span
class="pcrr7t-">data</span> declaration may assign labels to the fields of the constructor, using the record
syntax (<span
class="pcrr7t-">C</span><span
class="pcrr7t-">&#x00A0;{</span><span
class="pcrr7t-">&#x00A0;...</span><span
class="pcrr7t-">&#x00A0;}</span>). Constructors using field labels may be freely mixed with constructors without them. A
constructor with associated field labels may still be used as an ordinary constructor; features using labels
are simply a shorthand for operations using an underlying positional constructor. The arguments to
the positional constructor occur in the same order as the labeled fields. For example, the declaration
<div class="quote">
<div class="verbatim" id="verbatim-31">
&#x00A0;&#x00A0;data&#x00A0;C&#x00A0;=&#x00A0;F&#x00A0;{&#x00A0;f1,f2&#x00A0;::&#x00A0;Int,&#x00A0;f3&#x00A0;::&#x00A0;Bool&#x00A0;}
</div>
<p class="noindent"></div>
<p class="noindent"> defines a type and constructor identical to the one produced by
<div class="quote">
<div class="verbatim" id="verbatim-32">
&#x00A0;&#x00A0;data&#x00A0;C&#x00A0;=&#x00A0;F&#x00A0;Int&#x00A0;Int&#x00A0;Bool
</div>
<p class="noindent"></div>
<p class="noindent"> Operations using field labels are described in Section&#x00A0;<a
href="haskellch3.html#x8-490003.15">3.15<!--tex4ht:ref: field-ops --></a>. A <span
class="pcrr7t-">data</span> declaration may use the same field label
in multiple constructors as long as the typing of the field is the same in all cases after type synonym
expansion. A label cannot be shared by more than one type in scope. Field names share the top level
namespace with ordinary variables and class methods and must not conflict with other top level names in
scope.
<p class="noindent"> The pattern <span
class="pcrr7t-">F</span><span
class="pcrr7t-">&#x00A0;{}</span> matches any value built with constructor <span
class="pcrr7t-">F</span>, <span
class="ptmri7t-">whether or not</span> <span
class="pcrr7t-">F</span> <span
class="ptmri7t-">was declared with record</span>
<span
class="ptmri7t-">syntax</span>.
<p class="noindent"> <span class="paragraphHead"><a
id="x10-710004.2.1"></a><span
class="ptmb7t-">Strictness Flags</span></span>
<a
id="dx10-71001"></a>
Whenever a data constructor is applied, each argument to the constructor is evaluated if and only if the corresponding
type in the algebraic datatype declaration has a strictness flag, denoted by an exclamation point, &#8220;<span
class="pcrr7t-">!</span>&#8221;. <a
id="dx10-71002"></a>Lexically, &#8220;<span
class="pcrr7t-">!</span>&#8221; is
an ordinary varsym not a <span
class="cmmi-10">reservedop</span>; it has special significance only in the context of the argument types of a data
declaration.
<div class="center"
>
<p class="noindent">
<div class="fbox"><div class="minipage"><p class="noindent"> <span class="likeparagraphHead"><a
id="x10-720004.2.1"></a>Translation:</span>
A declaration of the form
<span
class="pcrr7t-">data</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;K</span><span
class="cmmi-10">&#x00A0;s</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;s</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span>
where each <span
class="cmmi-10">s</span><sub><span
class="cmmi-7">i</span></sub> is either of the form <span
class="pcrr7t-">!</span><span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub> or <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub>, replaces every occurrence of <span
class="cmmi-10">K</span> in an expression by
<span
class="pcrr7t-">(\</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">x</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;x</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">-&#x003E;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">((</span><span
class="cmmi-10">K</span><span
class="cmmi-10">&#x00A0;op</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;x</span><sub><span
class="cmr-7">1</span></sub><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;op</span><sub><span
class="cmr-7">2</span></sub><span
class="cmmi-10">&#x00A0;x</span><sub><span
class="cmr-7">2</span></sub><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;op</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;x</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmr-10">)</span>
where <span
class="cmmi-10">op</span><sub><span
class="cmmi-7">i</span></sub> is the non-strict apply function <span
class="pcrr7t-">$</span> if <span
class="cmmi-10">s</span><sub><span
class="cmmi-7">i</span></sub> is of the form <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub>, and <span
class="cmmi-10">op</span><sub><span
class="cmmi-7">i</span></sub> is the strict apply function
<span
class="pcrr7t-">$!</span> (see Section&#x00A0;<a
href="haskellch6.html#x13-1260006.2">6.2<!--tex4ht:ref: strict-eval --></a>) if <span
class="cmmi-10">s</span><sub><span
class="cmmi-7">i</span></sub> is of the form <span
class="pcrr7t-">!</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">i</span></sub>. Pattern matching on <span
class="cmmi-10">K</span> is not affected by strictness
flags. </div></div>
</div>
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.2.2 </span> <a
id="x10-730004.2.2"></a>Type Synonym Declarations</h4>
<a
id="dx10-73001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-64" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-64-1g"><col
id="TBL-64-1" /><col
id="TBL-64-2" /><col
id="TBL-64-3" /><col
id="TBL-64-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-64-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-64-1-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-64-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-64-1-3"
class="td11"> <span
class="pcrr7t-">type</span><span
class="cmmi-10">&#x00A0;simpletype</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;type </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-64-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-64-2-1"
class="td11"> <span
class="cmmi-10">simpletype </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-64-2-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-64-2-3"
class="td11"> <span
class="cmmi-10">tycon</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmmi-7">k</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-64-2-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr></table></div></div>
<a
id="dx10-73002"></a>
<a
id="dx10-73003"></a>
<p class="noindent"> A type synonym declaration introduces a new type that is equivalent to an old type. It has the form
<span
class="pcrr7t-">type</span><span
class="cmmi-10">&#x00A0;T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;t</span>
which introduces a new type constructor, <span
class="cmmi-10">T</span> . The type <span
class="cmr-10">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">t</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmr-10">)</span> is equivalent to the type <span
class="cmmi-10">t</span><span
class="cmr-10">[</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x2215;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x2215;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmr-10">]</span>. The
type variables <span
class="cmmi-10">u</span><sub><span
class="cmr-7">1</span></sub> through <span
class="cmmi-10">u</span><sub><span
class="cmmi-7">k</span></sub> must be distinct and are scoped only over <span
class="cmmi-10">t</span>; it is a static error for any other type variable
to appear in <span
class="cmmi-10">t</span>. The kind of the new type constructor <span
class="cmmi-10">T</span> is of the form <span
class="cmmi-10">&kappa;</span><sub><span
class="cmr-7">1</span></sub> <span
class="cmsy-10">&rarr;</span><span
class="cmmi-10">&hellip;</span> <span
class="cmsy-10">&rarr; </span><span
class="cmmi-10">&kappa;</span><sub><span
class="cmmi-7">k</span></sub> <span
class="cmsy-10">&rarr; </span><span
class="cmmi-10">&kappa; </span>where the kinds <span
class="cmmi-10">&kappa;</span><sub><span
class="cmmi-7">i</span></sub> of the
arguments <span
class="cmmi-10">u</span><sub><span
class="cmmi-7">i</span></sub> and <span
class="cmmi-10">&kappa;</span> of the right hand side <span
class="cmmi-10">t</span> are determined by kind inference as described in Section&#x00A0;<a
href="#x10-970004.6">4.6<!--tex4ht:ref: kindinference --></a><a
id="dx10-73004"></a><a
id="dx10-73005"></a>. For
example, the following definition can be used to provide an alternative way of writing the list type constructor:
<div class="quote">
<div class="verbatim" id="verbatim-33">
&#x00A0;&#x00A0;type&#x00A0;List&#x00A0;=&#x00A0;[]
</div>
<p class="noindent"></div>
<p class="noindent"> Type constructor symbols <span
class="cmmi-10">T</span> introduced by type synonym declarations cannot be partially applied; it is a static error
to use <span
class="cmmi-10">T</span> without the full number of arguments.
<p class="noindent"> Although recursive and mutually recursive datatypes are allowed, <a
id="dx10-73006"></a><a
id="dx10-73007"></a> this is not so for type synonyms, <span
class="ptmri7t-">unless an</span>
<span
class="ptmri7t-">algebraic datatype intervenes</span>. For example,
<div class="quote">
<div class="verbatim" id="verbatim-34">
&#x00A0;&#x00A0;type&#x00A0;Rec&#x00A0;a&#x00A0;&#x00A0;&#x00A0;=&#x00A0;&#x00A0;[Circ&#x00A0;a]
&#x00A0;<br />&#x00A0;&#x00A0;data&#x00A0;Circ&#x00A0;a&#x00A0;&#x00A0;=&#x00A0;&#x00A0;Tag&#x00A0;[Rec&#x00A0;a]
</div>
<p class="noindent"></div>
<p class="noindent"> is allowed, whereas
<div class="quote">
<div class="verbatim" id="verbatim-35">
&#x00A0;&#x00A0;type&#x00A0;Rec&#x00A0;a&#x00A0;&#x00A0;&#x00A0;=&#x00A0;&#x00A0;[Circ&#x00A0;a]&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;invalid
&#x00A0;<br />&#x00A0;&#x00A0;type&#x00A0;Circ&#x00A0;a&#x00A0;&#x00A0;=&#x00A0;&#x00A0;[Rec&#x00A0;a]&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;invalid
</div>
<p class="noindent"></div>
<p class="noindent"> is not. Similarly, <span
class="pcrr7t-">type</span><span
class="pcrr7t-">&#x00A0;Rec</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;=</span><span
class="pcrr7t-">&#x00A0;[Rec</span><span
class="pcrr7t-">&#x00A0;a]</span> is not allowed.
<p class="noindent"> Type synonyms are a convenient, but strictly syntactic, mechanism to make type signatures more readable. A
synonym and its definition are completely interchangeable, except in the instance type of an <span
class="pcrr7t-">instance</span> declaration
(Section&#x00A0;<a
href="#x10-770004.3.2">4.3.2<!--tex4ht:ref: instance-decls --></a>).
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.2.3 </span> <a
id="x10-740004.2.3"></a>Datatype Renamings</h4>
<a
id="dx10-74001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-65" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-65-1g"><col
id="TBL-65-1" /><col
id="TBL-65-2" /><col
id="TBL-65-3" /><col
id="TBL-65-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-65-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-65-1-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-65-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-65-1-3"
class="td11"> <span
class="pcrr7t-">newtype</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">context</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;simpletype</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;newconstr</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">deriving</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-65-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-65-2-1"
class="td11"> <span
class="cmmi-10">newconstr </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-65-2-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-65-2-3"
class="td11"> <span
class="cmmi-10">con</span><span
class="cmmi-10">&#x00A0;atype </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-65-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-65-3-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-65-3-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-65-3-3"
class="td11"> <span
class="cmmi-10">con</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;var</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;type</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-65-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-65-4-1"
class="td11"> <span
class="cmmi-10">simpletype </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-65-4-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-65-4-3"
class="td11"> <span
class="cmmi-10">tycon</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmmi-7">k</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-65-4-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr></table></div></div>
<a
id="dx10-74002"></a>
<a
id="dx10-74003"></a>
<a
id="dx10-74004"></a>
<p class="noindent"> A declaration of the form
<span
class="pcrr7t-">newtype</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;N</span><span
class="cmmi-10">&#x00A0;t</span>
introduces a new type whose representation is the same as an existing type. The type <span
class="pcrr7t-">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="pcrr7t-">)</span> renames the
datatype <span
class="cmmi-10">t</span>. It differs from a type synonym in that it creates a distinct type that must be explicitly coerced to or from
the original type. Also, unlike type synonyms, <span
class="pcrr7t-">newtype</span> may be used to define recursive types. The constructor <span
class="cmmi-10">N</span> in
an expression coerces a value from type <span
class="cmmi-10">t</span> to type <span
class="pcrr7t-">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="pcrr7t-">)</span>. Using <span
class="cmmi-10">N</span> in a pattern coerces a value from type
<span
class="pcrr7t-">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="pcrr7t-">)</span> to type <span
class="cmmi-10">t</span>. These coercions may be implemented without execution time overhead; <span
class="pcrr7t-">newtype</span> does not
change the underlying representation of an object.
<p class="noindent"> New instances (see Section <a
href="#x10-770004.3.2">4.3.2<!--tex4ht:ref: instance-decls --></a>) can be defined for a type defined by <span
class="pcrr7t-">newtype</span> but may not be
defined for a type synonym. A type created by <span
class="pcrr7t-">newtype</span> differs from an algebraic datatype in that the
representation of an algebraic datatype has an extra level of indirection. This difference may make access to
the representation less efficient. The difference is reflected in different rules for pattern matching (see
Section&#x00A0;<a
href="haskellch3.html#x8-580003.17">3.17<!--tex4ht:ref: pattern-matching --></a>). Unlike algebraic datatypes, the newtype constructor <span
class="cmmi-10">N</span> is <span
class="ptmri7t-">unlifted</span>, so that <span
class="cmmi-10">N</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span> is the same as
<span
class="cmsy-10">&perp;</span>.
<p class="noindent"> The following examples clarify the differences between <span
class="pcrr7t-">data</span> (algebraic datatypes), <span
class="pcrr7t-">type</span> (type synonyms), and
<span
class="pcrr7t-">newtype</span> (renaming types.) Given the declarations
<div class="quote">
<div class="verbatim" id="verbatim-36">
&#x00A0;&#x00A0;data&#x00A0;D1&#x00A0;=&#x00A0;D1&#x00A0;Int
&#x00A0;<br />&#x00A0;&#x00A0;data&#x00A0;D2&#x00A0;=&#x00A0;D2&#x00A0;!Int
&#x00A0;<br />&#x00A0;&#x00A0;type&#x00A0;S&#x00A0;=&#x00A0;Int
&#x00A0;<br />&#x00A0;&#x00A0;newtype&#x00A0;N&#x00A0;=&#x00A0;N&#x00A0;Int
&#x00A0;<br />&#x00A0;&#x00A0;d1&#x00A0;(D1&#x00A0;i)&#x00A0;=&#x00A0;42
&#x00A0;<br />&#x00A0;&#x00A0;d2&#x00A0;(D2&#x00A0;i)&#x00A0;=&#x00A0;42
&#x00A0;<br />&#x00A0;&#x00A0;s&#x00A0;i&#x00A0;=&#x00A0;42
&#x00A0;<br />&#x00A0;&#x00A0;n&#x00A0;(N&#x00A0;i)&#x00A0;=&#x00A0;42
</div>
<p class="noindent"></div>
<p class="noindent"> the expressions <span
class="pcrr7t-">(d1</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">)</span>, <span
class="pcrr7t-">(d2</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">)</span> and <span
class="pcrr7t-">(d2</span><span
class="pcrr7t-">&#x00A0;(D2</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">))</span> are all equivalent to <span
class="cmsy-10">&perp;</span>, whereas <span
class="pcrr7t-">(n</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">)</span>, <span
class="pcrr7t-">(n</span><span
class="pcrr7t-">&#x00A0;(N</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">))</span>,
<span
class="pcrr7t-">(d1</span><span
class="pcrr7t-">&#x00A0;(D1</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">))</span> and <span
class="pcrr7t-">(s</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">)</span> are all equivalent to <span
class="pcrr7t-">42</span>. In particular, <span
class="pcrr7t-">(N</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">)</span> is equivalent to <span
class="cmsy-10">&perp;</span> while <span
class="pcrr7t-">(D1</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&perp;</span><span
class="pcrr7t-">)</span> is not
equivalent to <span
class="cmsy-10">&perp;</span>.
<p class="noindent"> The optional deriving part of a <span
class="pcrr7t-">newtype</span> declaration is treated in the same way as the deriving component of a
<span
class="pcrr7t-">data</span> declaration; see Section&#x00A0;<a
href="#x10-780004.3.3">4.3.3<!--tex4ht:ref: derived-decls --></a>.
<p class="noindent"> A <span
class="pcrr7t-">newtype</span> declaration may use field-naming syntax, though of course there may only be one field. Thus:
<div class="quote">
<div class="verbatim" id="verbatim-37">
&#x00A0;&#x00A0;newtype&#x00A0;Age&#x00A0;=&#x00A0;Age&#x00A0;{&#x00A0;unAge&#x00A0;::&#x00A0;Int&#x00A0;}
</div>
<p class="noindent"></div>
<p class="noindent"> brings into scope both a constructor and a de-constructor:
<div class="quote">
<div class="verbatim" id="verbatim-38">
&#x00A0;&#x00A0;Age&#x00A0;&#x00A0;&#x00A0;::&#x00A0;Int&#x00A0;-&#x003E;&#x00A0;Age
&#x00A0;<br />&#x00A0;&#x00A0;unAge&#x00A0;::&#x00A0;Age&#x00A0;-&#x003E;&#x00A0;Int
</div>
<p class="noindent"></div>
<p class="noindent">
<h3 class="sectionHead"><span class="titlemark">4.3 </span> <a
id="x10-750004.3"></a>Type Classes and Overloading</h3>
<a
id="dx10-75001"></a>
<a
id="dx10-75002"></a>
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.3.1 </span> <a
id="x10-760004.3.1"></a>Class Declarations</h4>
<a
id="dx10-76001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-66" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-66-1g"><col
id="TBL-66-1" /><col
id="TBL-66-2" /><col
id="TBL-66-3" /><col
id="TBL-66-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-66-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-1-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-66-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-1-3"
class="td11"> <span
class="pcrr7t-">class</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">scontext</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;tycls</span><span
class="cmmi-10">&#x00A0;tyvar</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;cdecls</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-66-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-2-1"
class="td11"> <span
class="cmmi-10">scontext </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-66-2-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-2-3"
class="td11"> <span
class="cmmi-10">simpleclass </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-66-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-3-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-66-3-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-3-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;simpleclass</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;simpleclass</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-3-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-66-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-4-1"
class="td11"> <span
class="cmmi-10">simpleclass </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-66-4-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-4-3"
class="td11"> <span
class="cmmi-10">qtycls</span><span
class="cmmi-10">&#x00A0;tyvar </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-66-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-5-1"
class="td11"> <span
class="cmmi-10">cdecls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-66-5-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-5-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;cdecl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;cdecl</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-5-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-66-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-6-1"
class="td11"> <span
class="cmmi-10">cdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-66-6-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-6-3"
class="td11"> <span
class="cmmi-10">gendecl </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-66-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-66-7-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-66-7-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-66-7-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;var</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;rhs </span></td>
</tr></table></div></div>
<a
id="dx10-76002"></a>
<a
id="dx10-76003"></a>
<a
id="dx10-76004"></a>
<a
id="dx10-76005"></a>
<a
id="dx10-76006"></a>
<p class="noindent"> A <span
class="ptmri7t-">class declaration </span>introduces a new class and the operations (<span
class="ptmri7t-">class methods</span>) on it. A class declaration has the
general form:
<div class="array"> <table id="TBL-67" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-67-1g"><col
id="TBL-67-1" /><col
id="TBL-67-2" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:right;"
><div class="td11"> <span
class="pcrr7t-">class</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;C</span><span
class="cmmi-10">&#x00A0;u</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;cdecls</span> </div></td>
</tr></table> </div>
This introduces a new class name <span
class="cmmi-10">C</span>; the type variable <span
class="cmmi-10">u</span> is scoped only over the class method signatures in the class
body. The context <span
class="cmmi-10">cx</span> specifies the superclasses<a
id="dx10-76007"></a> of <span
class="cmmi-10">C</span>, as described below; the only type variable that may be referred
to in <span
class="cmmi-10">cx</span> is <span
class="cmmi-10">u</span>.
<p class="noindent"> The superclass relation must not be cyclic; i.e.&#x00A0;it must form a directed acyclic graph.<a
id="dx10-76008"></a>
<p class="noindent"> The <span
class="cmmi-10">cdecls</span> part of a <span
class="pcrr7t-">class</span> declaration contains three kinds of declarations:
<ul class="itemize1">
<li class="itemize">The class declaration introduces new <span
class="ptmri7t-">class methods</span> <a
id="dx10-76009"></a><span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub>, whose scope extends outside the <span
class="pcrr7t-">class</span>
declaration. The class methods of a class declaration are precisely the <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub> for which there is an explicit
type signature
<span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;cx</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">i</span></sub>
in <span
class="cmmi-10">cdecls</span>. Class methods share the top level namespace with variable bindings and field names; they
must not conflict with other top level bindings in scope. That is, a class method can not have the same
name as a top level definition, a field name, or another class method.
<p class="noindent"> The type of the top-level class method <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub> is:
<span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub> <span
class="cmr-10">:: </span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">u,</span><span class="overline"><span
class="cmmi-10">w</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">Cu,cx</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmr-10">) </span><span
class="cmsy-10">&rArr; </span><span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub>
The <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub> must mention <span
class="cmmi-10">u</span>; it may mention type variables <span class="overline"><span
class="cmmi-10">w</span></span> other than <span
class="cmmi-10">u</span>, in which case the type of <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub> is
polymorphic in both <span
class="cmmi-10">u</span> and <span class="overline"><span
class="cmmi-10">w</span></span>. The <span
class="cmmi-10">cx</span><sub><span
class="cmmi-7">i</span></sub> may constrain only <span class="overline"><span
class="cmmi-10">w</span></span>; in particular, the <span
class="cmmi-10">cx</span><sub><span
class="cmmi-7">i</span></sub> may not constrain <span
class="cmmi-10">u</span>. For
example:
<div class="quote">
<div class="verbatim" id="verbatim-39">
&#x00A0;&#x00A0;class&#x00A0;Foo&#x00A0;a&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;op&#x00A0;::&#x00A0;Num&#x00A0;b&#x00A0;=&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;b&#x00A0;-&#x003E;&#x00A0;a
</div>
<p class="noindent"></div>
<p class="noindent"> Here the type of <span
class="pcrr7t-">op</span> is <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a,</span><span
class="cmmi-10">&#x00A0;b.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="pcrr7t-">Foo</span><span
class="cmmi-10">&#x00A0;a,</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Num</span><span
class="cmmi-10">&#x00A0;b</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;b</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span>.
</li>
<li class="itemize">The <span
class="cmmi-10">cdecls</span> may also contain a <span
class="ptmri7t-">fixity declaration </span>for any of the class methods (but for no other values).
<a
id="dx10-76010"></a>However, since class methods declare top-level values, the fixity declaration for a class method may
alternatively appear at top level, outside the class declaration.
</li>
<li class="itemize">Lastly, the <span
class="cmmi-10">cdecls</span> may contain a <span
class="ptmri7t-">default class method</span> <a
id="dx10-76011"></a>for any of the <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub>. The default class method for <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub> is used
if no binding for it is given in a particular <span
class="pcrr7t-">instance</span> declaration (see Section&#x00A0;<a
href="#x10-770004.3.2">4.3.2<!--tex4ht:ref: instance-decls --></a>). The default method
declaration is a normal value definition, except that the left hand side may only be a variable or function
definition. For example:
<div class="quote">
<div class="verbatim" id="verbatim-40">
&#x00A0;&#x00A0;class&#x00A0;Foo&#x00A0;a&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;op1,&#x00A0;op2&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;(op1,&#x00A0;op2)&#x00A0;=&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> is not permitted, because the left hand side of the default declaration is a pattern.</li></ul>
<p class="noindent"> Other than these cases, no other declarations are permitted in <span
class="cmmi-10">cdecls</span>.
<p class="noindent"> A <span
class="pcrr7t-">class</span> declaration with no <span
class="pcrr7t-">where</span> part <a
id="dx10-76012"></a>may be useful for combining a collection of classes into a larger one that
inherits all of the class methods in the original ones. For example:
<div class="quote">
<div class="verbatim" id="verbatim-41">
&#x00A0;&#x00A0;class&#x00A0;&#x00A0;(Read&#x00A0;a,&#x00A0;Show&#x00A0;a)&#x00A0;=&#x003E;&#x00A0;Textual&#x00A0;a
</div>
<p class="noindent"></div>
<p class="noindent"> In such a case, if a type is an instance of all superclasses,<a
id="dx10-76013"></a> it is not <span
class="ptmri7t-">automatically </span>an instance of the subclass, even
though the subclass has no immediate class methods. The <span
class="pcrr7t-">instance</span> declaration must be given explicitly with no
<span
class="pcrr7t-">where</span> part. <a
id="dx10-76014"></a>
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.3.2 </span> <a
id="x10-770004.3.2"></a>Instance Declarations</h4>
<a
id="dx10-77001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-68" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-68-1g"><col
id="TBL-68-1" /><col
id="TBL-68-2" /><col
id="TBL-68-3" /><col
id="TBL-68-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-68-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-1-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-68-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-1-3"
class="td11"> <span
class="pcrr7t-">instance</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">scontext</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;qtycls</span><span
class="cmmi-10">&#x00A0;inst</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;idecls</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-2-1"
class="td11"> <span
class="cmmi-10">inst </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-68-2-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-2-3"
class="td11"> <span
class="cmmi-10">gtycon </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-3-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-68-3-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-3-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;gtycon</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-3-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;tyvars</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;distinct</span><span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-4-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-68-4-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-4-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-4-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">2</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;tyvars</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;distinct</span><span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-5-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-68-5-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-5-3"
class="td11"> <span
class="pcrr7t-">[</span><span
class="cmmi-10">&#x00A0;tyvar</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">]</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-6-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-68-6-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-6-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">-&#x003E;</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">2</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-6-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">tyvar</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;and</span><span
class="cmmi-10">&#x00A0;tyvar</span><sub><span
class="cmr-7">2</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;distinct</span><span
class="cmr-10">) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-7-1"
class="td11"> <span
class="cmmi-10">idecls </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-68-7-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-7-3"
class="td11"> <span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;idecl</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">;</span><span
class="cmmi-10">&#x00A0;idecl</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-7-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-8-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-8-1"
class="td11"> <span
class="cmmi-10">idecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-68-8-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-8-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;var</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;rhs </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-68-9-"><td style="white-space:nowrap; text-align:left;" id="TBL-68-9-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-68-9-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-9-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-68-9-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">empty</span><span
class="cmr-10">) </span></td>
</tr></table></div></div>
<a
id="dx10-77002"></a>
<a
id="dx10-77003"></a>
<a
id="dx10-77004"></a>
<a
id="dx10-77005"></a>
<a
id="dx10-77006"></a>
<a
id="dx10-77007"></a>
<a
id="dx10-77008"></a>
<p class="noindent"> An <span
class="ptmri7t-">instance declaration </span>introduces an instance of a class. Let
<span
class="pcrr7t-">class</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;C</span><span
class="cmmi-10">&#x00A0;u</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;cbody</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span>
be a <span
class="pcrr7t-">class</span> declaration. The general form of the corresponding instance declaration is:
<span
class="pcrr7t-">instance</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmsy-10">&prime;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;C</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">{</span><span
class="cmmi-10">&#x00A0;d</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span>
where <span
class="cmmi-10">k </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0</span>. The type <span
class="cmr-10">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmr-10">)</span> must take the form of a type constructor <span
class="cmmi-10">T</span> applied to simple type variables
<span
class="cmmi-10">u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub>; furthermore, <span
class="cmmi-10">T</span> must not be a type synonym<a
id="dx10-77009"></a>, and the <span
class="cmmi-10">u</span><sub><span
class="cmmi-7">i</span></sub> must all be distinct.
<p class="noindent"> This prohibits instance declarations such as:
<div class="quote">
<div class="verbatim" id="verbatim-42">
&#x00A0;&#x00A0;instance&#x00A0;C&#x00A0;(a,a)&#x00A0;where&#x00A0;...
&#x00A0;<br />&#x00A0;&#x00A0;instance&#x00A0;C&#x00A0;(Int,a)&#x00A0;where&#x00A0;...
&#x00A0;<br />&#x00A0;&#x00A0;instance&#x00A0;C&#x00A0;[[a]]&#x00A0;where&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> The declarations <span
class="cmmi-10">d</span> may contain bindings only for the class methods<a
id="dx10-77010"></a> of <span
class="cmmi-10">C</span>. It is illegal to give a binding for a class
method that is not in scope, but the name under which it is in scope is immaterial; in particular, it may be a qualified
name. (This rule is identical to that used for subordinate names in export lists &#8212; Section&#x00A0;<a
href="haskellch5.html#x11-1000005.2">5.2<!--tex4ht:ref: export --></a>.) For
example, this is legal, even though <span
class="pcrr7t-">range</span> is in scope only with the qualified name <span
class="pcrr7t-">Data.Ix.range</span>.
<div class="quote">
<div class="verbatim" id="verbatim-43">
&#x00A0;&#x00A0;module&#x00A0;A&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;import&#x00A0;qualified&#x00A0;Data.Ix
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;instance&#x00A0;Data.Ix.Ix&#x00A0;T&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;range&#x00A0;=&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> The declarations may not contain any type signatures or fixity declarations,<a
id="dx10-77011"></a><a
id="dx10-77012"></a> since these have already been given in
the <span
class="pcrr7t-">class</span> declaration. As in the case of default class methods <a
id="dx10-77013"></a>(Section&#x00A0;<a
href="#x10-760004.3.1">4.3.1<!--tex4ht:ref: class-decls --></a>), the method declarations must take the
form of a variable or function definition.
<p class="noindent"> If no binding is given for some class method then the corresponding default class method <a
id="dx10-77014"></a>in the <span
class="pcrr7t-">class</span> declaration
is used (if present); if such a default does not exist then the class method of this instance is bound to <span
class="pcrr7t-">undefined</span>
and no compile-time error results.
<p class="noindent"> An <span
class="pcrr7t-">instance</span> declaration that makes the type <span
class="cmmi-10">T</span> to be an instance of class <span
class="cmmi-10">C</span> is called a <span
class="ptmri7t-">C-T instance declaration</span>
<a
id="dx10-77015"></a>and is subject to these static restrictions:
<ul class="itemize1">
<li class="itemize">A type may not be declared as an instance of a particular class more than once in the program.
</li>
<li class="itemize">The class and type must have the same kind; this can be determined using kind inference as described
in Section&#x00A0;<a
href="#x10-970004.6">4.6<!--tex4ht:ref: kindinference --></a><a
id="dx10-77016"></a><a
id="dx10-77017"></a>.
</li>
<li class="itemize">Assume that the type variables in the instance type <span
class="cmr-10">(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;u</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmr-10">)</span> satisfy the constraints in the instance context
<span
class="cmmi-10">cx</span><span
class="cmsy-10">&prime;</span>. Under this assumption, the following two conditions must also be satisfied:
<ol class="enumerate1" >
<li
class="enumerate" id="x10-77019x1">The constraints expressed by the superclass context <span
class="cmmi-10">cx</span><span
class="cmr-10">[(</span><span
class="cmmi-10">T</span><span
class="cmmi-10">&#x00A0;u</span><span
class="cmr-10">1</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;uk</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x2215;u</span><span
class="cmr-10">]</span> of <span
class="cmmi-10">C</span> must be satisfied.
In other words, <span
class="cmmi-10">T</span> must be an instance of each of <span
class="cmmi-10">C</span>&#8217;s superclasses and the contexts of all superclass
instances must be implied by <span
class="cmmi-10">cx</span><span
class="cmsy-10">&prime;</span>.
</li>
<li
class="enumerate" id="x10-77021x2">Any constraints on the type variables in the instance type that are required for the class method
declarations in <span
class="cmmi-10">d</span> to be well-typed must also be satisfied.</li></ol>
<p class="noindent"> In fact, except in pathological cases it is possible to infer from the instance declaration the most general
instance context <span
class="cmmi-10">cx</span><span
class="cmsy-10">&prime;</span> satisfying the above two constraints, but it is nevertheless mandatory to write an explicit
instance context.</li></ul>
<p class="noindent"> The following example illustrates the restrictions imposed by superclass instances:
<div class="quote">
<div class="verbatim" id="verbatim-44">
&#x00A0;&#x00A0;class&#x00A0;Foo&#x00A0;a&#x00A0;=&#x003E;&#x00A0;Bar&#x00A0;a&#x00A0;where&#x00A0;...
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;instance&#x00A0;(Eq&#x00A0;a,&#x00A0;Show&#x00A0;a)&#x00A0;=&#x003E;&#x00A0;Foo&#x00A0;[a]&#x00A0;where&#x00A0;...
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;instance&#x00A0;Num&#x00A0;a&#x00A0;=&#x003E;&#x00A0;Bar&#x00A0;[a]&#x00A0;where&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> This example is valid Haskell. Since <span
class="pcrr7t-">Foo</span> is a superclass of <span
class="pcrr7t-">Bar</span>, the second instance declaration is only valid if
<span
class="pcrr7t-">[a]</span> is an instance of <span
class="pcrr7t-">Foo</span> under the assumption <span
class="pcrr7t-">Num</span><span
class="pcrr7t-">&#x00A0;a</span>. The first instance declaration does indeed
say that <span
class="pcrr7t-">[a]</span> is an instance of <span
class="pcrr7t-">Foo</span> under this assumption, because <span
class="pcrr7t-">Eq</span> and <span
class="pcrr7t-">Show</span> are superclasses of
<span
class="pcrr7t-">Num</span>.
<p class="noindent"> If the two instance declarations instead read like this:
<div class="quote">
<div class="verbatim" id="verbatim-45">
&#x00A0;&#x00A0;instance&#x00A0;Num&#x00A0;a&#x00A0;=&#x003E;&#x00A0;Foo&#x00A0;[a]&#x00A0;where&#x00A0;...
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;instance&#x00A0;(Eq&#x00A0;a,&#x00A0;Show&#x00A0;a)&#x00A0;=&#x003E;&#x00A0;Bar&#x00A0;[a]&#x00A0;where&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> then the program would be invalid. The second instance declaration is valid only if <span
class="pcrr7t-">[a]</span> is an instance of <span
class="pcrr7t-">Foo</span> under
the assumptions <span
class="pcrr7t-">(Eq</span><span
class="pcrr7t-">&#x00A0;a,</span><span
class="pcrr7t-">&#x00A0;Show</span><span
class="pcrr7t-">&#x00A0;a)</span>. But this does not hold, since <span
class="pcrr7t-">[a]</span> is only an instance of <span
class="pcrr7t-">Foo</span> under the
stronger assumption <span
class="pcrr7t-">Num</span><span
class="pcrr7t-">&#x00A0;a</span>.
<p class="noindent"> Further examples of <span
class="pcrr7t-">instance</span> declarations may be found in Chapter&#x00A0;<a
href="haskellch9.html#x16-1710009">9<!--tex4ht:ref: stdprelude --></a>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.3.3 </span> <a
id="x10-780004.3.3"></a>Derived Instances</h4>
<a
id="dx10-78001"></a>
<p class="noindent"> As mentioned in Section&#x00A0;<a
href="#x10-690004.2.1">4.2.1<!--tex4ht:ref: datatype-decls --></a>, <span
class="pcrr7t-">data</span> and <span
class="pcrr7t-">newtype</span> declarations contain an optional <span
class="pcrr7t-">deriving</span> form. If the form
is included, then <span
class="ptmri7t-">derived instance declarations </span>are automatically generated for the datatype in each of the named
classes. These instances are subject to the same restrictions as user-defined instances. When deriving a class <span
class="cmmi-10">C</span> for a
type <span
class="cmmi-10">T</span> , instances for all superclasses of <span
class="cmmi-10">C</span> must exist for <span
class="cmmi-10">T</span> , either via an explicit <span
class="pcrr7t-">instance</span> declaration or by
including the superclass in the <span
class="pcrr7t-">deriving</span> clause.
<p class="noindent"> Derived instances provide convenient commonly-used operations for user-defined datatypes. For example, derived
instances for datatypes in the class <span
class="pcrr7t-">Eq</span> define the operations <span
class="pcrr7t-">==</span> and <span
class="pcrr7t-">/=</span>, freeing the programmer from the need to
define them.
<p class="noindent"> The only classes in the Prelude for which derived instances are allowed are <span
class="pcrr7t-">Eq</span><a
id="dx10-78002"></a>, <span
class="pcrr7t-">Ord</span><a
id="dx10-78003"></a>, <span
class="pcrr7t-">Enum</span><a
id="dx10-78004"></a>, <span
class="pcrr7t-">Bounded</span><a
id="dx10-78005"></a>, <span
class="pcrr7t-">Show</span><a
id="dx10-78006"></a>, and
<span
class="pcrr7t-">Read</span><a
id="dx10-78007"></a>, all mentioned in Figure&#x00A0;<a
href="haskellch6.html#x13-1270011">6.1<!--tex4ht:ref: standard-classes --></a>. The precise details of how the derived instances are generated for each of these
classes are provided in Chapter&#x00A0;<a
href="haskellch11.html#x18-18200011">11<!--tex4ht:ref: derived-appendix --></a>, including a specification of when such derived instances are possible. Classes
defined by the standard libraries may also be derivable.
<p class="noindent"> A static error results if it is not possible to derive an <span
class="pcrr7t-">instance</span> declaration over a class named in a <span
class="pcrr7t-">deriving</span>
form. For example, not all datatypes can properly support class methods in <span
class="pcrr7t-">Enum</span>.<a
id="dx10-78008"></a> It is also a static error to give an
explicit <span
class="pcrr7t-">instance</span> declaration for a class that is also derived.
<p class="noindent"> If the <span
class="pcrr7t-">deriving</span> form is omitted from a <span
class="pcrr7t-">data</span> or <span
class="pcrr7t-">newtype</span> declaration, then <span
class="ptmri7t-">no </span>instance declarations are derived
for that datatype; that is, omitting a <span
class="pcrr7t-">deriving</span> form is equivalent to including an empty deriving form:
<span
class="pcrr7t-">deriving</span><span
class="pcrr7t-">&#x00A0;()</span>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.3.4 </span> <a
id="x10-790004.3.4"></a>Ambiguous Types, and Defaults for Overloaded Numeric Operations</h4>
<a
id="dx10-79001"></a>
<a
id="dx10-79002"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-69" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-69-1g"><col
id="TBL-69-1" /><col
id="TBL-69-2" /><col
id="TBL-69-3" /><col
id="TBL-69-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-69-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-69-1-1"
class="td11"> <span
class="cmmi-10">topdecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-69-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-69-1-3"
class="td11"> <span
class="pcrr7t-">default</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">(</span><span
class="cmmi-10">type</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;type</span><sub><span
class="cmmi-7">n</span></sub><span
class="pcrr7t-">)</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-69-1-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0) </span></td>
</tr></table>
</div></div>
<a
id="dx10-79003"></a>
<p class="noindent"> A problem inherent with Haskell-style overloading is the possibility of an <span
class="ptmri7t-">ambiguous type</span>. <a
id="dx10-79004"></a>For example, using the
<span
class="pcrr7t-">read</span> and <span
class="pcrr7t-">show</span> functions defined in Chapter&#x00A0;<a
href="haskellch11.html#x18-18200011">11<!--tex4ht:ref: derived-appendix --></a>, and supposing that just <span
class="pcrr7t-">Int</span> and <span
class="pcrr7t-">Bool</span> are members of <span
class="pcrr7t-">Read</span> and
<span
class="pcrr7t-">Show</span>, then the expression
<div class="quote">
<div class="verbatim" id="verbatim-46">
&#x00A0;&#x00A0;let&#x00A0;x&#x00A0;=&#x00A0;read&#x00A0;"..."&#x00A0;in&#x00A0;show&#x00A0;x&#x00A0;&#x00A0;--&#x00A0;invalid
</div>
<p class="noindent"></div>
<p class="noindent"> is ambiguous, because the types for <span
class="pcrr7t-">show</span> and <span
class="pcrr7t-">read</span>,
<div class="array"> <table id="TBL-70" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-70-1g"><col
id="TBL-70-1" /><col
id="TBL-70-2" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">show</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmr-10">::</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Show</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">String</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">read</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmr-10">::</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Read</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">String</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span> </div></td>
</tr></table> </div>
could be satisfied by instantiating <span
class="pcrr7t-">a</span> as either <span
class="pcrr7t-">Int</span> in both cases, or <span
class="pcrr7t-">Bool</span>. Such expressions are considered ill-typed,
a static error.
<p class="noindent"> We say that an expression <span
class="pcrr7t-">e</span> has an <span
class="ptmri7t-">ambiguous type </span>if, in its type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span>, there is a type variable <span
class="cmmi-10">u</span> in <span class="overline"><span
class="cmmi-10">u</span></span> that
occurs in <span
class="cmmi-10">cx</span> but not in <span
class="cmmi-10">t</span>. Such types are invalid.
<p class="noindent"> For example, the earlier expression involving <span
class="pcrr7t-">show</span> and <span
class="pcrr7t-">read</span> has an ambiguous type since its type is
<span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Show</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a,</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Read</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">String</span>.
<p class="noindent"> Ambiguous types can only be circumvented by input from the user. One way is through the use of <span
class="ptmri7t-">expression</span>
<span
class="ptmri7t-">type-signatures</span> <a
id="dx10-79005"></a>as described in Section&#x00A0;<a
href="haskellch3.html#x8-560003.16">3.16<!--tex4ht:ref: expression-type-sigs --></a>. For example, for the ambiguous expression given earlier, one could
write:
<div class="quote">
<div class="verbatim" id="verbatim-47">
&#x00A0;&#x00A0;let&#x00A0;x&#x00A0;=&#x00A0;read&#x00A0;"..."&#x00A0;in&#x00A0;show&#x00A0;(x::Bool)
</div>
<p class="noindent"></div>
<p class="noindent"> which disambiguates the type.
<p class="noindent"> Occasionally, an otherwise ambiguous expression needs to be made the same type as some variable, rather than
being given a fixed type with an expression type-signature. This is the purpose of the function <span
class="pcrr7t-">asTypeOf</span>
(Chapter&#x00A0;<a
href="haskellch9.html#x16-1710009">9<!--tex4ht:ref: stdprelude --></a>): <span
class="cmmi-10">x</span> <span
class="pcrr7t-">&#8216;asTypeOf&#8216;</span> <span
class="cmmi-10">y</span> has the value of <span
class="cmmi-10">x</span>, but <span
class="cmmi-10">x</span> and <span
class="cmmi-10">y</span> are forced to have the same type. For example,
<div class="quote">
<div class="verbatim" id="verbatim-48">
&#x00A0;&#x00A0;approxSqrt&#x00A0;x&#x00A0;=&#x00A0;encodeFloat&#x00A0;1&#x00A0;(exponent&#x00A0;x&#x00A0;&#8216;div&#8216;&#x00A0;2)&#x00A0;&#8216;asTypeOf&#8216;&#x00A0;x
</div>
<p class="noindent"></div>
<p class="noindent"> (See Section&#x00A0;<a
href="haskellch6.html#x13-1410006.4.6">6.4.6<!--tex4ht:ref: coercion --></a> for a description of <span
class="pcrr7t-">encodeFloat</span> and <span
class="pcrr7t-">exponent</span>.)
<p class="noindent"> Ambiguities in the class <span
class="pcrr7t-">Num</span><a
id="dx10-79006"></a> are most common, so Haskell provides another way to resolve them&#8212;with a <span
class="ptmri7t-">default</span>
<span
class="ptmri7t-">declaration</span>:
<span
class="pcrr7t-">default</span><span
class="pcrr7t-">&#x00A0;(</span><span
class="cmmi-10">t</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;t</span><sub><span
class="cmmi-7">n</span></sub><span
class="pcrr7t-">)</span>
where <span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">0</span>, and each <span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub> must be a type for which <span
class="pcrr7t-">Num</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">t</span><sub><span
class="cmmi-7">i</span></sub> holds. In situations where an ambiguous type is
discovered, an ambiguous type variable, <span
class="cmmi-10">v</span>, is defaultable if:
<ul class="itemize1">
<li class="itemize"><span
class="cmmi-10">v</span> appears only in constraints of the form <span
class="cmmi-10">C</span><span
class="cmmi-10">&#x00A0;v</span>, where <span
class="cmmi-10">C</span> is a class, and
</li>
<li class="itemize">at least one of these classes is a numeric class, (that is, <span
class="pcrr7t-">Num</span> or a subclass of <span
class="pcrr7t-">Num</span>), and
</li>
<li class="itemize">all of these classes are defined in the Prelude or a standard library (Figures&#x00A0;<a
href="haskellch6.html#x13-1350142">6.2<!--tex4ht:ref: basic-numeric-1 --></a>&#8211;<a
href="haskellch6.html#x13-1350573">6.3<!--tex4ht:ref: basic-numeric-2 --></a> show the numeric
classes, and Figure&#x00A0;<a
href="haskellch6.html#x13-1270011">6.1<!--tex4ht:ref: standard-classes --></a> shows the classes defined in the Prelude.)</li></ul>
<p class="noindent"> Each defaultable variable is replaced by the first type in the default list that is an instance of all the ambiguous
variable&#8217;s classes. It is a static error if no such type is found.
<p class="noindent"> Only one default declaration is permitted per module, and its effect is limited to that module. If no default
declaration is given in a module then it assumed to be:
<div class="quote">
<div class="verbatim" id="verbatim-49">
&#x00A0;&#x00A0;default&#x00A0;(Integer,&#x00A0;Double)
</div>
<p class="noindent"></div>
<p class="noindent"> The empty default declaration, <span
class="pcrr7t-">default</span><span
class="pcrr7t-">&#x00A0;()</span>, turns off all defaults in a module.
<p class="noindent">
<h3 class="sectionHead"><span class="titlemark">4.4 </span> <a
id="x10-800004.4"></a>Nested Declarations</h3>
<p class="noindent"> The following declarations may be used in any declaration list, including the top level of a module.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.4.1 </span> <a
id="x10-810004.4.1"></a>Type Signatures</h4>
<a
id="dx10-81001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-71" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-71-1g"><col
id="TBL-71-1" /><col
id="TBL-71-2" /><col
id="TBL-71-3" /><col
id="TBL-71-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-71-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-71-1-1"
class="td11"> <span
class="cmmi-10">gendecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-71-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-71-1-3"
class="td11"> <span
class="cmmi-10">vars</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">context</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;type </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-71-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-71-2-1"
class="td11"> <span
class="cmmi-10">vars </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-71-2-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-71-2-3"
class="td11"> <span
class="cmmi-10">var</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;var</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-71-2-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr></table></div></div>
<a
id="dx10-81002"></a>
<a
id="dx10-81003"></a>
<p class="noindent"> A type signature specifies types for variables, possibly with respect to a context. A type signature has the
form:
<span
class="cmmi-10">v</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;v</span><sub><span
class="cmmi-7">n</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span>
which is equivalent to asserting <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">::</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=&#x003E;</span><span
class="cmmi-10">&#x00A0;t</span> for each <span
class="cmmi-10">i</span> from <span
class="cmr-10">1</span> to <span
class="cmmi-10">n</span>. Each <span
class="cmmi-10">v</span><sub><span
class="cmmi-7">i</span></sub> must have a value binding in the
same declaration list that contains the type signature; i.e.&#x00A0;it is invalid to give a type signature for a variable bound in
an outer scope. Moreover, it is invalid to give more than one type signature for one variable, even if the signatures are
identical.
<p class="noindent"> As mentioned in Section&#x00A0;<a
href="#x10-650004.1.2">4.1.2<!--tex4ht:ref: type-syntax --></a>, every type variable appearing in a signature is universally quantified over that
signature, and hence the scope of a type variable is limited to the type signature that contains it. For example, in the
following declarations
<div class="quote">
<div class="verbatim" id="verbatim-50">
&#x00A0;&#x00A0;f&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a
&#x00A0;<br />&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;=&#x00A0;x&#x00A0;::&#x00A0;a&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;invalid
</div>
<p class="noindent"></div>
<p class="noindent"> the <span
class="pcrr7t-">a</span>&#8217;s in the two type signatures are quite distinct. Indeed, these declarations contain a static error,
since <span
class="pcrr7t-">x</span> does not have type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;a</span>. (The type of <span
class="pcrr7t-">x</span> is dependent on the type of <span
class="pcrr7t-">f</span>; there is currently no
way in Haskell to specify a signature for a variable with a dependent type; this is explained in Section
<a
href="#x10-920004.5.4">4.5.4<!--tex4ht:ref: monomorphism --></a>.)
<p class="noindent"> If a given program includes a signature for a variable <span
class="cmmi-10">f</span>, then each use of <span
class="cmmi-10">f</span> is treated as having the
declared type. It is a static error if the same type cannot also be inferred for the defining occurrence of
<span
class="cmmi-10">f</span>.
<p class="noindent"> If a variable <span
class="cmmi-10">f</span> is defined without providing a corresponding type signature declaration, then each use of <span
class="cmmi-10">f</span> outside its
own declaration group (see Section&#x00A0;<a
href="#x10-880004.5">4.5<!--tex4ht:ref: dependencyanalysis --></a>) is treated as having the corresponding inferred, or <span
class="ptmri7t-">principal </span>type <a
id="dx10-81004"></a>. However,
to ensure that type inference is still possible, the defining occurrence, and all uses of <span
class="cmmi-10">f</span> within its declaration group
must have the same monomorphic type (from which the principal type is obtained by generalization, as described in
Section&#x00A0;<a
href="#x10-900004.5.2">4.5.2<!--tex4ht:ref: generalization --></a>).
<p class="noindent"> For example, if we define
<div class="quote">
<div class="verbatim" id="verbatim-51">
&#x00A0;&#x00A0;sqr&#x00A0;x&#x00A0;&#x00A0;=&#x00A0;&#x00A0;x&#x22C6;x
</div>
<p class="noindent"></div>
<p class="noindent"> then the principal type is <span
class="pcrr7t-">sqr</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmr-10">::</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Num</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span>, which allows applications such as <span
class="pcrr7t-">sqr</span><span
class="pcrr7t-">&#x00A0;5</span> or
<span
class="pcrr7t-">sqr</span><span
class="pcrr7t-">&#x00A0;0.1</span>. It is also valid to declare a more specific type, such as
<div class="quote">
<div class="verbatim" id="verbatim-52">
&#x00A0;&#x00A0;sqr&#x00A0;::&#x00A0;Int&#x00A0;-&#x003E;&#x00A0;Int
</div>
<p class="noindent"></div>
<p class="noindent"> but now applications such as <span
class="pcrr7t-">sqr</span><span
class="pcrr7t-">&#x00A0;0.1</span> are invalid. Type signatures such as
<div class="quote">
<div class="verbatim" id="verbatim-53">
&#x00A0;&#x00A0;sqr&#x00A0;::&#x00A0;(Num&#x00A0;a,&#x00A0;Num&#x00A0;b)&#x00A0;=&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;b&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;invalid
&#x00A0;<br />&#x00A0;&#x00A0;sqr&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;invalid
</div>
<p class="noindent"></div>
<p class="noindent"> are invalid, as they are more general than the principal type of <span
class="pcrr7t-">sqr</span>.
<p class="noindent"> Type signatures can also be used to support <span
class="ptmri7t-">polymorphic recursion</span><a
id="dx10-81005"></a>. The following definition is pathological, but
illustrates how a type signature can be used to specify a type more general than the one that would be inferred:
<div class="quote">
<div class="verbatim" id="verbatim-54">
&#x00A0;&#x00A0;data&#x00A0;T&#x00A0;a&#x00A0;&#x00A0;=&#x00A0;&#x00A0;K&#x00A0;(T&#x00A0;Int)&#x00A0;(T&#x00A0;a)
&#x00A0;<br />&#x00A0;&#x00A0;f&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;::&#x00A0;T&#x00A0;a&#x00A0;-&#x003E;&#x00A0;a
&#x00A0;<br />&#x00A0;&#x00A0;f&#x00A0;(K&#x00A0;x&#x00A0;y)&#x00A0;=&#x00A0;&#x00A0;if&#x00A0;f&#x00A0;x&#x00A0;==&#x00A0;1&#x00A0;then&#x00A0;f&#x00A0;y&#x00A0;else&#x00A0;undefined
</div>
<p class="noindent"></div>
<p class="noindent"> If we remove the signature declaration, the type of <span
class="pcrr7t-">f</span> will be inferred as <span
class="pcrr7t-">T</span><span
class="pcrr7t-">&#x00A0;Int</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;Int</span> due to the first recursive
call for which the argument to <span
class="pcrr7t-">f</span> is <span
class="pcrr7t-">T</span><span
class="pcrr7t-">&#x00A0;Int</span>. Polymorphic recursion allows the user to supply the more general type
signature, <span
class="pcrr7t-">T</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.4.2 </span> <a
id="x10-820004.4.2"></a>Fixity Declarations</h4>
<a
id="dx10-82001"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-72" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-72-1g"><col
id="TBL-72-1" /><col
id="TBL-72-2" /><col
id="TBL-72-3" /><col
id="TBL-72-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-72-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-72-1-1"
class="td11"> <span
class="cmmi-10">gendecl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-72-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-72-1-3"
class="td11"> <span
class="cmmi-10">fixity</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">integer</span><span
class="cmr-10">]</span><span
class="cmmi-10">&#x00A0;ops </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-72-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-72-2-1"
class="td11"> <span
class="cmmi-10">fixity </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-72-2-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-72-2-3"
class="td11"> <span
class="pcrr7t-">infixl</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">infixr</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">infix</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-72-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-72-3-1"
class="td11"> <span
class="cmmi-10">ops </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-72-3-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-72-3-3"
class="td11"> <span
class="cmmi-10">op</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">,</span><span
class="cmmi-10">&#x00A0;op</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-72-3-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1) </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-72-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-72-4-1"
class="td11"> <span
class="cmmi-10">op </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-72-4-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-72-4-3"
class="td11"> <span
class="cmmi-10">varop</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;conop </span></td>
</tr></table></div></div>
<a
id="dx10-82002"></a>
<a
id="dx10-82003"></a>
<a
id="dx10-82004"></a>
<a
id="dx10-82005"></a>
<p class="noindent"> A fixity declaration gives the fixity and binding precedence of one or more operators. The <span
class="cmmi-10">integer</span> in a
fixity declaration must be in the range <span
class="cmr-10">0</span> to <span
class="cmr-10">9</span>. A fixity declaration may appear anywhere that a type
signature appears and, like a type signature, declares a property of a particular operator. Also like a type
signature, a fixity declaration can only occur in the same sequence of declarations as the declaration of
the operator itself, and at most one fixity declaration may be given for any operator. (Class methods
are a minor exception; their fixity declarations can occur either in the class declaration itself or at top
level.)
<p class="noindent"> There are three kinds of fixity, non-, left- and right-associativity (<span
class="pcrr7t-">infix</span>, <span
class="pcrr7t-">infixl</span>, and <span
class="pcrr7t-">infixr</span>, respectively), and
ten precedence levels, 0 to 9 inclusive (level 0 binds least tightly, and level 9 binds most tightly). If the <span
class="cmmi-10">digit</span> is
omitted, level 9 is assumed. Any operator lacking a fixity declaration is assumed to be <span
class="pcrr7t-">infixl</span><span
class="pcrr7t-">&#x00A0;9</span> (See Section&#x00A0;<a
href="haskellch3.html#x8-220003">3<!--tex4ht:ref: expressions --></a> for
more on the use of fixities). Table&#x00A0;<a
href="#x10-820061">4.1<!--tex4ht:ref: prelude-fixities --></a> lists the fixities and precedences of the operators defined in the
Prelude.
<div class="table">
<p class="noindent"> <a
id="x10-820061"></a><hr class="float" /><div class="float"
>
<div
class="centerline"> <!--tex4ht:inline--><div class="tabular"> <table id="TBL-73" class="tabular"
cellspacing="0" cellpadding="0" rules="groups"
><colgroup id="TBL-73-1g"><col
id="TBL-73-1" /></colgroup><colgroup id="TBL-73-2g"><col
id="TBL-73-2" /></colgroup><colgroup id="TBL-73-3g"><col
id="TBL-73-3" /></colgroup><colgroup id="TBL-73-4g"><col
id="TBL-73-4" /></colgroup><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-1-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-1-1"
class="td11"> Prec- </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-1-2"
class="td11"> Left associative </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-1-3"
class="td11"> Non-associative </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-1-4"
class="td11"> Right associative </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-73-2-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-2-1"
class="td11"> edence </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-2-2"
class="td11"> operators </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-2-3"
class="td11"> operators </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-2-4"
class="td11"> operators </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-3-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-3-1"
class="td11"> 9 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-3-2"
class="td11"> <span
class="pcrr7t-">!!</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-3-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-3-4"
class="td11"> <span
class="pcrr7t-">.</span> </td></tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-4-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-4-1"
class="td11"> 8 </td> <td style="white-space:nowrap; text-align:left;" id="TBL-73-4-2"
class="td11"> </td> <td style="white-space:nowrap; text-align:left;" id="TBL-73-4-3"
class="td11"> </td> <td style="white-space:nowrap; text-align:left;" id="TBL-73-4-4"
class="td11"> <span
class="pcrr7t-">^</span> , <span
class="pcrr7t-">^^</span> , <span
class="pcrr7t-">&#x22C6;&#x22C6;</span></td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-5-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-5-1"
class="td11"> 7 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-5-2"
class="td11"> <span
class="pcrr7t-">&#x22C6;</span>, <span
class="pcrr7t-">/</span>, <span
class="pcrr7t-">&#8216;div&#8216;</span>, </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-5-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-5-4"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-73-6-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-6-1"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-6-2"
class="td11"> <span
class="pcrr7t-">&#8216;mod&#8216;</span>, <span
class="pcrr7t-">&#8216;rem&#8216;</span>, <span
class="pcrr7t-">&#8216;quot&#8216;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-6-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-6-4"
class="td11"> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-7-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-7-1"
class="td11"> 6 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-7-2"
class="td11"> <span
class="pcrr7t-">+</span>, <span
class="pcrr7t-">-</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-7-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-7-4"
class="td11"> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-8-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-8-1"
class="td11"> 5 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-8-2"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-8-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-8-4"
class="td11"> <span
class="pcrr7t-">:</span>, <span
class="pcrr7t-">++</span> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-9-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-9-1"
class="td11"> 4 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-9-2"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-9-3"
class="td11"> <span
class="pcrr7t-">==</span>, <span
class="pcrr7t-">/=</span>, <span
class="pcrr7t-">&#x003C;</span>, <span
class="pcrr7t-">&#x003C;=</span>, <span
class="pcrr7t-">&#x003E;</span>, <span
class="pcrr7t-">&#x003E;=</span>, </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-9-4"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-73-10-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-10-1"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-10-2"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-10-3"
class="td11"> <span
class="pcrr7t-">&#8216;elem&#8216;</span>, <span
class="pcrr7t-">&#8216;notElem&#8216;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-10-4"
class="td11"> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-11-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-11-1"
class="td11"> 3 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-11-2"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-11-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-11-4"
class="td11"> <span
class="pcrr7t-">&amp;&amp;</span> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-12-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-12-1"
class="td11"> 2 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-12-2"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-12-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-12-4"
class="td11"> <span
class="pcrr7t-">||</span> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-13-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-13-1"
class="td11"> 1 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-13-2"
class="td11"> <span
class="pcrr7t-">&#x003E;&#x003E;</span>, <span
class="pcrr7t-">&#x003E;&#x003E;=</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-13-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-13-4"
class="td11"> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-14-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-14-1"
class="td11"> 0 </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-14-2"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-14-3"
class="td11"> </td><td style="white-space:nowrap; text-align:left;" id="TBL-73-14-4"
class="td11"> <span
class="pcrr7t-">$</span>, <span
class="pcrr7t-">$!</span>, <span
class="pcrr7t-">&#8216;seq&#8216;</span> </td>
</tr><tr
class="hline"><td><hr /></td><td><hr /></td><td><hr /></td><td><hr /></td></tr><tr
style="vertical-align:baseline;" id="TBL-73-15-"><td style="white-space:nowrap; text-align:right;" id="TBL-73-15-1"
class="td11"> </td></tr></table> </div></div>
<br /><div class="caption"
><span class="id">Table&#x00A0;4.1: </span><span
class="content">Precedences and fixities of prelude operators</span></div><!--tex4ht:label?: x10-820061 -->
<a
id="dx10-82007"></a>
<a
id="dx10-82008"></a>
<a
id="dx10-82009"></a>
<a
id="dx10-82010"></a>
<a
id="dx10-82011"></a>
<a
id="dx10-82012"></a>
<a
id="dx10-82013"></a>
<a
id="dx10-82014"></a>
<a
id="dx10-82015"></a>
<a
id="dx10-82016"></a>
<a
id="dx10-82017"></a>
<a
id="dx10-82018"></a>
<a
id="dx10-82019"></a>
<a
id="dx10-82020"></a>
<a
id="dx10-82021"></a>
<a
id="dx10-82022"></a>
<a
id="dx10-82023"></a>
<a
id="dx10-82024"></a>
<a
id="dx10-82025"></a>
<a
id="dx10-82026"></a>
<a
id="dx10-82027"></a>
<a
id="dx10-82028"></a>
<a
id="dx10-82029"></a>
<a
id="dx10-82030"></a>
<a
id="dx10-82031"></a>
<a
id="dx10-82032"></a>
<a
id="dx10-82033"></a>
</div><hr class="endfloat" />
</div>
<p class="noindent"> Fixity is a property of a particular entity (constructor or variable), just like its type; fixity is not a property of that
entity&#8217;s <span
class="ptmri7t-">name</span>. For example:
<div class="quote">
<div class="verbatim" id="verbatim-55">
&#x00A0;&#x00A0;module&#x00A0;Bar(&#x00A0;op&#x00A0;)&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;infixr&#x00A0;7&#x00A0;&#8216;op&#8216;
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;op&#x00A0;=&#x00A0;...
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;module&#x00A0;Foo&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;import&#x00A0;qualified&#x00A0;Bar
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;infix&#x00A0;3&#x00A0;&#8216;op&#8216;
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;a&#x00A0;&#8216;op&#8216;&#x00A0;b&#x00A0;=&#x00A0;(a&#x00A0;&#8216;Bar.op&#8216;&#x00A0;b)&#x00A0;+&#x00A0;1
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;=&#x00A0;let
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;p&#x00A0;&#8216;op&#8216;&#x00A0;q&#x00A0;=&#x00A0;(p&#x00A0;&#8216;Foo.op&#8216;&#x00A0;q)&#x00A0;&#x22C6;&#x00A0;2
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;in&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> Here, <span
class="pcrr7t-">&#8216;Bar.op&#8216;</span> is <span
class="pcrr7t-">infixr</span><span
class="pcrr7t-">&#x00A0;7</span>, <span
class="pcrr7t-">&#8216;Foo.op&#8216;</span> is <span
class="pcrr7t-">infix</span><span
class="pcrr7t-">&#x00A0;3</span>, and the nested definition of <span
class="pcrr7t-">op</span> in <span
class="pcrr7t-">f</span>&#8217;s right-hand side
has the default fixity of <span
class="pcrr7t-">infixl</span><span
class="pcrr7t-">&#x00A0;9</span>. (It would also be possible to give a fixity to the nested definition of <span
class="pcrr7t-">&#8216;op&#8216;</span> with a
nested fixity declaration.)
<h4 class="subsectionHead"><span class="titlemark">4.4.3 </span> <a
id="x10-830004.4.3"></a>Function and Pattern Bindings</h4>
<a
id="dx10-83001"></a>
<a
id="dx10-83002"></a>
<div class="flushleft"
>
<p class="noindent">
<!--tex4ht:inline--><div class="tabular"> <table id="TBL-74" class="tabular"
cellspacing="0" cellpadding="0"
><colgroup id="TBL-74-1g"><col
id="TBL-74-1" /><col
id="TBL-74-2" /><col
id="TBL-74-3" /><col
id="TBL-74-4" /></colgroup><tr
style="vertical-align:baseline;" id="TBL-74-1-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-1-1"
class="td11"> <span
class="cmmi-10">decl </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-74-1-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-1-3"
class="td11"> <span
class="cmr-10">(</span><span
class="cmmi-10">funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">pat</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0;rhs</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-2-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-2-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-74-3-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-3-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-4-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-4-1"
class="td11"> <span
class="cmmi-10">funlhs </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-74-4-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-4-3"
class="td11"> <span
class="cmmi-10">var</span><span
class="cmmi-10">&#x00A0;apat</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">{</span><span
class="cmmi-10">&#x00A0;apat</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">} </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-5-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-5-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-5-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-5-3"
class="td11"> <span
class="cmmi-10">pat</span><span
class="cmmi-10">&#x00A0;varop</span><span
class="cmmi-10">&#x00A0;pat</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-6-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-6-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-6-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-6-3"
class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">&#x00A0;funlhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">)</span><span
class="cmmi-10">&#x00A0;apat</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">{</span><span
class="cmmi-10">&#x00A0;apat</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmsy-10">} </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-7-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-7-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td></tr><tr
style="vertical-align:baseline;" id="TBL-74-8-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-8-1"
class="td11"></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-9-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-9-1"
class="td11"> <span
class="cmmi-10">rhs </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-74-9-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-9-3"
class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;exp</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;decls</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-10-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-10-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-10-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-10-3"
class="td11"> <span
class="cmmi-10">gdrhs</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="pcrr7t-">where</span><span
class="cmmi-10">&#x00A0;decls</span><span
class="cmr-10">] </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-11-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-11-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-12-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-12-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-13-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-13-1"
class="td11"> <span
class="cmmi-10">gdrhs </span></td><td style="white-space:nowrap; text-align:center;" id="TBL-74-13-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-13-3"
class="td11"> <span
class="cmmi-10">guards</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;exp</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">[</span><span
class="cmmi-10">gdrhs</span><span
class="cmr-10">]</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-14-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-14-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-15-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-15-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-16-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-16-1"
class="td11"> <span
class="cmmi-10">guards</span> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-16-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-16-3"
class="td11"> <span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;guard</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;guard</span><sub><span
class="cmmi-7">n</span></sub> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-16-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1)</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-17-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-17-1"
class="td11"> <span
class="ptmri7t-">&#x00A0; </span></td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-18-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-18-1"
class="td11"> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-19-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-19-1"
class="td11"> <a
id="dx10-83003"></a><span
class="cmmi-10">guard</span> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-19-2"
class="td11"> <span
class="cmsy-10">&rarr;</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-19-3"
class="td11"> <span
class="cmmi-10">pat</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">&#x003C;-</span><span
class="cmmi-10">&#x00A0;infixexp</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-19-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>pattern&#x00A0;guard<span
class="cmr-10">)</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-20-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-20-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-20-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-20-3"
class="td11"> <span
class="pcrr7t-">let</span><span
class="cmmi-10">&#x00A0;decls</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-20-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>local&#x00A0;declaration<span
class="cmr-10">)</span> </td>
</tr><tr
style="vertical-align:baseline;" id="TBL-74-21-"><td style="white-space:nowrap; text-align:left;" id="TBL-74-21-1"
class="td11"> </td><td style="white-space:nowrap; text-align:center;" id="TBL-74-21-2"
class="td11"> <span
class="cmsy-10">|</span> </td><td style="white-space:nowrap; text-align:left;" id="TBL-74-21-3"
class="td11"> <span
class="cmmi-10">infixexp </span></td><td style="white-space:nowrap; text-align:left;" id="TBL-74-21-4"
class="td11"> <span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="ptmri7t-">&#x00A0;</span><span
class="cmr-10">(</span>boolean&#x00A0;guard<span
class="cmr-10">) </span></td>
</tr></table></div></div>
<a
id="dx10-83004"></a>
<a
id="dx10-83005"></a>
<a
id="dx10-83006"></a>
<a
id="dx10-83007"></a>
<a
id="dx10-83008"></a>
<a
id="dx10-83009"></a>
<p class="noindent"> We distinguish two cases within this syntax: a <span
class="ptmri7t-">pattern binding </span>occurs when the left hand side is a <span
class="cmmi-10">pat</span>; otherwise, the
binding is called a <span
class="ptmri7t-">function binding</span>. Either binding may appear at the top-level of a module or within a <span
class="pcrr7t-">where</span> or
<span
class="pcrr7t-">let</span> construct.
<p class="noindent">
<h5 class="subsubsectionHead"><span class="titlemark">4.4.3.1 </span> <a
id="x10-840004.4.3.1"></a>Function bindings</h5>
<a
id="dx10-84001"></a>
<p class="noindent"> A function binding binds a variable to a function value. The general form of a function binding for variable <span
class="cmmi-10">x</span>
is:
<div class="array"> <table id="TBL-75" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-75-1g"><col
id="TBL-75-1" /><col
id="TBL-75-2" /><col
id="TBL-75-3" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">x</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">p</span><sub><span
class="cmr-7">11</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;p</span><sub><span
class="cmr-7">1</span><span
class="cmmi-7">k</span></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">match</span><sub><span
class="cmr-7">1</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">&hellip;</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">x</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">p</span><sub><span
class="cmmi-7">n</span><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;p</span><sub><span
class="cmmi-7">nk</span></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">match</span><sub><span
class="cmmi-7">n</span></sub> </div></td>
</tr></table> </div>
where each <span
class="cmmi-10">p</span><sub><span
class="cmmi-7">ij</span></sub> is a pattern, and where each <span
class="cmmi-10">match</span><sub><span
class="cmmi-7">i</span></sub> is of the general form:
<div class="array"> <table id="TBL-76" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-76-1g"><col
id="TBL-76-1" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">where</span><span
class="pcrr7t-">&#x00A0;{</span><span
class="cmmi-10">&#x00A0;decls</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </div></td>
</tr></table> </div>
or
<div class="array"> <table id="TBL-77" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-77-1g"><col
id="TBL-77-1" /><col
id="TBL-77-2" /><col
id="TBL-77-3" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmmi-7">i</span><span
class="cmr-7">1</span></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmmi-7">i</span><span
class="cmr-7">1</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">&hellip;</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmmi-7">im</span><sub><span
class="cmmi-5">i</span></sub></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmmi-7">im</span><sub><span
class="cmmi-5">i</span></sub></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td colspan="2" style="white-space:nowrap; text-align:left;"
><div class="td11"> <div class="multicolumn" style="white-space:nowrap; text-align:left;"><span
class="pcrr7t-">where</span><span
class="pcrr7t-">&#x00A0;{</span><span
class="cmmi-10">&#x00A0;decls</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span></div>
</div></td></tr></table> </div>
and where <span
class="cmmi-10">n </span><span
class="cmsy-10">&ge; </span><span
class="cmr-10">1</span>, <span
class="cmr-10">1 </span><span
class="cmsy-10">&le; </span><span
class="cmmi-10">i </span><span
class="cmsy-10">&le; </span><span
class="cmmi-10">n</span>, <span
class="cmmi-10">m</span><sub><span
class="cmmi-7">i</span></sub> <span
class="cmsy-10">&ge; </span><span
class="cmr-10">1</span>. The former is treated as shorthand for a particular case of the latter,
namely:
<div class="array"> <table id="TBL-78" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-78-1g"><col
id="TBL-78-1" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">|</span><span
class="pcrr7t-">&#x00A0;True</span><span
class="pcrr7t-">&#x00A0;=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">where</span><span
class="pcrr7t-">&#x00A0;{</span><span
class="cmmi-10">&#x00A0;decls</span><sub><span
class="cmmi-7">i</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span> </div></td>
</tr></table> </div>
<p class="noindent"> Note that all clauses defining a function must be contiguous, and the number of patterns in each clause must be the
same. The set of patterns corresponding to each match must be <span
class="ptmri7t-">linear</span><a
id="dx10-84002"></a><a
id="dx10-84003"></a>&#8212;no variable is allowed to appear more than
once in the entire set.
<p class="noindent"> Alternative syntax is provided for binding functional values to infix operators. For example, these three function
definitions are all equivalent:
<div class="quote">
<div class="verbatim" id="verbatim-56">
&#x00A0;&#x00A0;plus&#x00A0;x&#x00A0;y&#x00A0;z&#x00A0;=&#x00A0;x+y+z
&#x00A0;<br />&#x00A0;&#x00A0;x&#x00A0;&#8216;plus&#8216;&#x00A0;y&#x00A0;=&#x00A0;\&#x00A0;z&#x00A0;-&#x003E;&#x00A0;x+y+z
&#x00A0;<br />&#x00A0;&#x00A0;(x&#x00A0;&#8216;plus&#8216;&#x00A0;y)&#x00A0;z&#x00A0;=&#x00A0;x+y+z
</div>
<p class="noindent"></div>
<p class="noindent"> Note that fixity resolution applies to the infix variants of the function binding in the same way as for expressions
(Section&#x00A0;<a
href="haskellch10.html#x17-18100010.6">10.6<!--tex4ht:ref: fixity-resolution --></a>). Applying fixity resolution to the left side of the equals in a function binding must leave the <span
class="cmmi-10">varop</span>
being defined at the top level. For example, if we are defining a new operator <span
class="pcrr7t-">##</span> with precedence 6, then this
definition would be illegal:
<div class="quote">
<div class="verbatim" id="verbatim-57">
&#x00A0;&#x00A0;a&#x00A0;##&#x00A0;b&#x00A0;:&#x00A0;xs&#x00A0;=&#x00A0;exp
</div>
<p class="noindent"></div>
<p class="noindent"> because <span
class="pcrr7t-">:</span> has precedence 5, so the left hand side resolves to <span
class="pcrr7t-">(a</span><span
class="pcrr7t-">&#x00A0;##</span><span
class="pcrr7t-">&#x00A0;x)</span><span
class="pcrr7t-">&#x00A0;:</span><span
class="pcrr7t-">&#x00A0;xs</span>, and this cannot be a pattern binding
because <span
class="pcrr7t-">(a</span><span
class="pcrr7t-">&#x00A0;##</span><span
class="pcrr7t-">&#x00A0;x)</span> is not a valid pattern.
<div class="center"
>
<p class="noindent">
<div class="fbox"><div class="minipage"><p class="noindent"> <span class="likeparagraphHead"><a
id="x10-850004.4.3.1"></a>Translation:</span>
The general binding form for functions is semantically equivalent to the equation (i.e.&#x00A0;simple pattern
binding):
<span
class="cmmi-10">x</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">=</span><span
class="pcrr7t-">&#x00A0;\</span><span
class="cmmi-10">&#x00A0;x</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">&#x00A0;x</span><sub><span
class="cmmi-7">k</span></sub><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">-&#x003E;</span><span
class="pcrr7t-">&#x00A0;case</span><span
class="pcrr7t-">&#x00A0;(</span><span
class="cmmi-10">x</span><sub><span
class="cmr-7">1</span></sub><span
class="pcrr7t-">,</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="pcrr7t-">,</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">x</span><sub><span
class="cmmi-7">k</span></sub><span
class="pcrr7t-">)</span><span
class="pcrr7t-">&#x00A0;of</span><div class="array"><table id="TBL-79" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-79-1g"><col
id="TBL-79-1" /><col
id="TBL-79-2" /><col
id="TBL-79-3" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">p</span><sub><span
class="cmr-7">11</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;p</span><sub><span
class="cmr-7">1</span><span
class="cmmi-7">k</span></sub><span
class="pcrr7t-">)</span><span
class="cmmi-10">&#x00A0;match</span><sub><span
class="cmr-7">1</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">&hellip;</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">(</span><span
class="cmmi-10">p</span><sub><span
class="cmmi-7">n</span><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&hellip;</span><span
class="cmmi-10">,</span><span
class="cmmi-10">&#x00A0;p</span><sub><span
class="cmmi-7">nk</span></sub><span
class="pcrr7t-">)</span><span
class="cmmi-10">&#x00A0;match</span><sub><span
class="cmmi-7">n</span></sub> </div></td></tr></table> </div>
where the <span
class="cmmi-10">x</span><sub><span
class="cmmi-7">i</span></sub> are new identifiers. </div></div>
</div>
<p class="noindent">
<h5 class="subsubsectionHead"><span class="titlemark">4.4.3.2 </span> <a
id="x10-860004.4.3.2"></a>Pattern bindings</h5>
<a
id="dx10-86001"></a>
<p class="noindent"> A pattern binding binds variables to values. A <span
class="ptmri7t-">simple </span>pattern binding has form <span
class="cmmi-10">p</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmr-10">=</span> <span
class="cmmi-10">&#x00A0;e</span>. <a
id="dx10-86002"></a>The pattern <span
class="cmmi-10">p</span> is
matched &#8220;lazily&#8221; as an irrefutable pattern<a
id="dx10-86003"></a>, as if there were an implicit <span
class="pcrr7t-">~</span> in front of it. See the translation in
Section&#x00A0;<a
href="haskellch3.html#x8-440003.12">3.12<!--tex4ht:ref: let-expressions --></a>.
<p class="noindent"> The <span
class="ptmri7t-">general </span>form of a pattern binding is <span
class="cmmi-10">p</span><span
class="cmmi-10">&#x00A0;match</span>, where a <span
class="cmmi-10">match</span> is the same structure as for function bindings
above; in other words, a pattern binding is:
<div class="array"> <table id="TBL-80" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-80-1g"><col
id="TBL-80-1" /><col
id="TBL-80-2" /><col
id="TBL-80-3" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:right;"
><div class="td11"> <span
class="cmmi-10">p</span> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> <span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmr-7">1</span></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmr-7">1</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:right;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> <span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmr-7">2</span></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmr-7">2</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:right;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> <span
class="cmmi-10">&hellip;</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:right;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> <span
class="pcrr7t-">|</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmmi-7">m</span></sub> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">=</span><span
class="cmmi-10">&#x00A0;e</span><sub><span
class="cmmi-7">m</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:right;"
><div class="td11"> </div></td><td colspan="2" style="white-space:nowrap; text-align:left;"
><div class="td11"> <div class="multicolumn" style="white-space:nowrap; text-align:left;"><span
class="pcrr7t-">where</span><span
class="pcrr7t-">&#x00A0;{</span><span
class="cmmi-10">&#x00A0;decls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">}</span></div>
</div></td></tr></table> </div>
<div class="center"
>
<p class="noindent">
<div class="fbox"><div class="minipage"><p class="noindent"><span class="likeparagraphHead"><a
id="x10-870004.4.3.2"></a>Translation:</span>
The pattern binding above is semantically equivalent to this simple pattern binding:
<div class="array"> <table id="TBL-81" class="array"
cellpadding="0" cellspacing="0"
><colgroup id="TBL-81-1g"><col
id="TBL-81-1" /><col
id="TBL-81-2" /><col
id="TBL-81-3" /></colgroup><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="cmmi-10">p</span> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> <span
class="pcrr7t-">=</span> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">let</span><span
class="cmmi-10">&#x00A0;decls</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">in</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">case</span><span
class="pcrr7t-">&#x00A0;()</span><span
class="pcrr7t-">&#x00A0;of</span><span
class="pcrr7t-">&#x00A0;</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;()</span><span
class="pcrr7t-">&#x00A0;|</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmr-7">1</span></sub><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">e</span><sub><span
class="cmr-7">1</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;|</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmr-7">2</span></sub><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">e</span><sub><span
class="cmr-7">2</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">&hellip;</span> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;|</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">gs</span><sub><span
class="cmmi-7">m</span></sub><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;</span><span
class="cmmi-10">e</span><sub><span
class="cmmi-7">m</span></sub> </div></td>
</tr><tr
style="vertical-align:baseline;"><td style="white-space:nowrap; text-align:left;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:center;"
><div class="td11"> </div></td><td style="white-space:nowrap; text-align:left;"
><div class="td11"> <span
class="pcrr7t-">&#x00A0;</span><span
class="pcrr7t-">&#x00A0;_</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;error</span><span
class="pcrr7t-">&#x00A0;"Unmatched</span><span
class="pcrr7t-">&#x00A0;pattern"</span> </div></td></tr></table> </div></div></div>
</div>
<p class="noindent">
<h3 class="sectionHead"><span class="titlemark">4.5 </span> <a
id="x10-880004.5"></a>Static Semantics of Function and Pattern Bindings</h3>
<p class="noindent"> The static semantics of the function and pattern bindings of a <span
class="pcrr7t-">let</span> expression or <span
class="pcrr7t-">where</span> clause are discussed in this
section.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.5.1 </span> <a
id="x10-890004.5.1"></a>Dependency Analysis</h4>
<p class="noindent"> In general the static semantics are given by applying the normal Hindley-Milner<a
id="dx10-89001"></a> inference rules. In order
to increase polymorphism, these rules are applied to groups of bindings identified by a <span
class="ptmri7t-">dependency</span>
<span
class="ptmri7t-">analysis</span>.
<p class="noindent"> A binding <span
class="cmmi-10">b</span><span
class="cmr-10">1</span> <span
class="ptmri7t-">depends </span>on a binding <span
class="cmmi-10">b</span><span
class="cmr-10">2</span> in the same list of declarations if either
<p class="noindent">
<ol class="enumerate1" >
<li
class="enumerate" id="x10-89003x1"><span
class="cmmi-10">b</span><span
class="cmr-10">1</span> contains a free identifier that has no type signature and is bound by <span
class="cmmi-10">b</span><span
class="cmr-10">2</span>, or
</li>
<li
class="enumerate" id="x10-89005x2"><span
class="cmmi-10">b</span><span
class="cmr-10">1</span> depends on a binding that depends on <span
class="cmmi-10">b</span><span
class="cmr-10">2</span>.</li></ol>
<p class="noindent"> A <span
class="ptmri7t-">declaration group </span>is a minimal set of mutually dependent bindings. Hindley-Milner type inference is applied to
each declaration group in dependency order. The order of declarations in <span
class="pcrr7t-">where</span>/<span
class="pcrr7t-">let</span> constructs is
irrelevant.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.5.2 </span> <a
id="x10-900004.5.2"></a>Generalization</h4>
<p class="noindent"> The Hindley-Milner type system assigns types to a let-expression in two stages:
<p class="noindent">
<ol class="enumerate1" >
<li
class="enumerate" id="x10-90002x1">The declaration groups are considered in dependency order. For each group, a type with no universal
quantification is inferred for each variable bound in the group. Then, all type variables that occur
in these types are universally quantified unless they are associated with bound variables in the type
environment; this is called generalization.
</li>
<li
class="enumerate" id="x10-90004x2">Finally, the body of the let-expression is typed.</li></ol>
<p class="noindent"> For example, consider the declaration
<div class="quote">
<div class="verbatim" id="verbatim-58">
&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;=&#x00A0;let&#x00A0;g&#x00A0;y&#x00A0;=&#x00A0;(y,y)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;in&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> The type of <span
class="pcrr7t-">g</span>&#8217;s definition is <span
class="cmmi-10">a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">a,a</span><span
class="cmr-10">)</span>. The generalization step attributes to <span
class="pcrr7t-">g</span> the polymorphic type
<span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">a,a</span><span
class="cmr-10">)</span>, after which the typing of the &#8220;<span
class="pcrr7t-">...</span>&#8221; part can proceed.
<p class="noindent"> When typing overloaded definitions, all the overloading constraints from a single declaration group are collected
together, to form the context for the type of each variable declared in the group. For example, in the definition:
<div class="quote">
<div class="verbatim" id="verbatim-59">
&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;=&#x00A0;let&#x00A0;g1&#x00A0;x&#x00A0;y&#x00A0;=&#x00A0;if&#x00A0;x&#x003E;y&#x00A0;then&#x00A0;show&#x00A0;x&#x00A0;else&#x00A0;g2&#x00A0;y&#x00A0;x
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;g2&#x00A0;p&#x00A0;q&#x00A0;=&#x00A0;g1&#x00A0;q&#x00A0;p
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;in&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> The types of the definitions of <span
class="pcrr7t-">g1</span> and <span
class="pcrr7t-">g2</span> are both <span
class="cmmi-10">a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">String</span>, and the accumulated constraints are
<span
class="pcrr7t-">Ord</span><span
class="cmmi-10">&#x00A0;a</span> (arising from the use of <span
class="pcrr7t-">&#x003E;</span>), and <span
class="pcrr7t-">Show</span><span
class="cmmi-10">&#x00A0;a</span> (arising from the use of <span
class="pcrr7t-">show</span>). The type variables appearing in this
collection of constraints are called the <span
class="ptmri7t-">constrained type variables</span>.
<p class="noindent"> The generalization step attributes to both <span
class="pcrr7t-">g1</span> and <span
class="pcrr7t-">g2</span> the type
<span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="pcrr7t-">Ord</span><span
class="cmmi-10">&#x00A0;a,</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Show</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmr-10">)</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">String</span>
Notice that <span
class="pcrr7t-">g2</span> is overloaded in the same way as <span
class="pcrr7t-">g1</span> even though the occurrences of <span
class="pcrr7t-">&#x003E;</span> and <span
class="pcrr7t-">show</span> are in the definition
of <span
class="pcrr7t-">g1</span>.
<p class="noindent"> If the programmer supplies explicit type signatures for more than one variable in a declaration group, the contexts of
these signatures must be identical up to renaming of the type variables.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.5.3 </span> <a
id="x10-910004.5.3"></a>Context Reduction Errors</h4>
<a
id="dx10-91001"></a>
<p class="noindent"> As mentioned in Section&#x00A0;<a
href="#x10-670004.1.4">4.1.4<!--tex4ht:ref: type-semantics --></a>, the context of a type may constrain only a type variable, or the application of a type
variable to one or more types. Hence, types produced by generalization must be expressed in a form in which all
context constraints have be reduced to this &#8220;head normal form&#8221;. Consider, for example, the definition:
<div class="quote">
<div class="verbatim" id="verbatim-60">
&#x00A0;&#x00A0;f&#x00A0;xs&#x00A0;y&#x00A0;&#x00A0;=&#x00A0;&#x00A0;xs&#x00A0;==&#x00A0;[y]
</div>
<p class="noindent"></div>
<p class="noindent"> Its type is given by
<div class="quote">
<div class="verbatim" id="verbatim-61">
&#x00A0;&#x00A0;f&#x00A0;::&#x00A0;Eq&#x00A0;a&#x00A0;=&#x003E;&#x00A0;[a]&#x00A0;-&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;Bool
</div>
<p class="noindent"></div>
<p class="noindent"> and not
<div class="quote">
<div class="verbatim" id="verbatim-62">
&#x00A0;&#x00A0;f&#x00A0;::&#x00A0;Eq&#x00A0;[a]&#x00A0;=&#x003E;&#x00A0;[a]&#x00A0;-&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;Bool
</div>
<p class="noindent"></div>
<p class="noindent"> Even though the equality is taken at the list type, the context must be simplified, using the instance declaration for <span
class="pcrr7t-">Eq</span>
on lists, before generalization. If no such instance is in scope, a static error occurs.
<p class="noindent"> Here is an example that shows the need for a constraint of the form <span
class="cmmi-10">C</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmr-10">(</span><span
class="cmmi-10">m</span><span
class="cmmi-10">&#x00A0;t</span><span
class="cmr-10">)</span> where m is one of the type variables
being generalized; that is, where the class <span
class="cmmi-10">C</span> applies to a type expression that is not a type variable or a type
constructor. Consider:
<div class="quote">
<div class="verbatim" id="verbatim-63">
&#x00A0;&#x00A0;f&#x00A0;::&#x00A0;(Monad&#x00A0;m,&#x00A0;Eq&#x00A0;(m&#x00A0;a))&#x00A0;=&#x003E;&#x00A0;a&#x00A0;-&#x003E;&#x00A0;m&#x00A0;a&#x00A0;-&#x003E;&#x00A0;Bool
&#x00A0;<br />&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;y&#x00A0;=&#x00A0;return&#x00A0;x&#x00A0;==&#x00A0;y
</div>
<p class="noindent"></div>
<p class="noindent"> The type of <span
class="pcrr7t-">return</span> is <span
class="pcrr7t-">Monad</span><span
class="pcrr7t-">&#x00A0;m</span><span
class="pcrr7t-">&#x00A0;=&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;m</span><span
class="pcrr7t-">&#x00A0;a</span>; the type of <span
class="pcrr7t-">(==)</span> is <span
class="pcrr7t-">Eq</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;=&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;Bool</span>. The type
of <span
class="pcrr7t-">f</span> should be therefore <span
class="pcrr7t-">(Monad</span><span
class="pcrr7t-">&#x00A0;m,</span><span
class="pcrr7t-">&#x00A0;Eq</span><span
class="pcrr7t-">&#x00A0;(m</span><span
class="pcrr7t-">&#x00A0;a))</span><span
class="pcrr7t-">&#x00A0;=&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;m</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;-&#x003E;</span><span
class="pcrr7t-">&#x00A0;Bool</span>, and the context cannot be
simplified further.
<p class="noindent"> The instance declaration derived from a data type <span
class="pcrr7t-">deriving</span> clause (see Section&#x00A0;<a
href="#x10-780004.3.3">4.3.3<!--tex4ht:ref: derived-decls --></a>) must, like any instance
declaration, have a <span
class="ptmri7t-">simple </span>context; that is, all the constraints must be of the form <span
class="cmmi-10">C</span><span
class="cmmi-10">&#x00A0;a</span>, where <span
class="cmmi-10">a</span> is a type variable. For
example, in the type
<div class="quote">
<div class="verbatim" id="verbatim-64">
&#x00A0;&#x00A0;data&#x00A0;Apply&#x00A0;a&#x00A0;b&#x00A0;=&#x00A0;App&#x00A0;(a&#x00A0;b)&#x00A0;&#x00A0;deriving&#x00A0;Show
</div>
<p class="noindent"></div>
<p class="noindent"> the derived Show instance will produce a context <span
class="pcrr7t-">Show</span><span
class="pcrr7t-">&#x00A0;(a</span><span
class="pcrr7t-">&#x00A0;b)</span>, which cannot be reduced and is not simple; thus a
static error results.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.5.4 </span> <a
id="x10-920004.5.4"></a>Monomorphism</h4>
<p class="noindent"> Sometimes it is not possible to generalize over all the type variables used in the type of the definition. For example,
consider the declaration
<div class="quote">
<div class="verbatim" id="verbatim-65">
&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;=&#x00A0;let&#x00A0;g&#x00A0;y&#x00A0;z&#x00A0;=&#x00A0;([x,y],&#x00A0;z)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;in&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> In an environment where <span
class="pcrr7t-">x</span> has type <span
class="cmmi-10">a</span>, the type of <span
class="pcrr7t-">g</span>&#8217;s definition is <span
class="cmmi-10">a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;b</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">([</span><span
class="cmmi-10">a</span><span
class="pcrr7t-">]</span><span
class="cmmi-10">,b</span><span
class="pcrr7t-">)</span>. The generalization step
attributes to <span
class="pcrr7t-">g</span> the type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;b.</span><span
class="cmmi-10">&#x00A0;</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;b</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rarr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">([</span><span
class="cmmi-10">a</span><span
class="pcrr7t-">]</span><span
class="cmmi-10">,b</span><span
class="pcrr7t-">)</span>; only <span
class="cmmi-10">b</span> can be universally quantified because
<span
class="cmmi-10">a</span> occurs in the type environment. We say that the type of <span
class="pcrr7t-">g</span> is <span
class="ptmri7t-">monomorphic in the type variable</span> <span
class="cmmi-10">a</span>.
<a
id="dx10-92001"></a>
<p class="noindent"> The effect of such monomorphism is that the first argument of all applications of <span
class="pcrr7t-">g</span> must be of a single type. For
example, it would be valid for the &#8220;<span
class="pcrr7t-">...</span>&#8221; to be
<div class="quote">
<div class="verbatim" id="verbatim-66">
&#x00A0;&#x00A0;(g&#x00A0;True,&#x00A0;g&#x00A0;False)
</div>
<p class="noindent"></div>
<p class="noindent"> (which would, incidentally, force <span
class="pcrr7t-">x</span> to have type <span
class="pcrr7t-">Bool</span>) but invalid for it to be
<div class="quote">
<div class="verbatim" id="verbatim-67">
&#x00A0;&#x00A0;(g&#x00A0;True,&#x00A0;g&#x00A0;'c')
</div>
<p class="noindent"></div>
<p class="noindent"> In general, a type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span> is said to be <span
class="ptmri7t-">monomorphic</span> <a
id="dx10-92002"></a>in the type variable <span
class="cmmi-10">a</span> if <span
class="cmmi-10">a</span> is free in <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;</span><span class="overline"><span
class="cmmi-10">u</span></span><span
class="cmmi-10">.</span><span
class="cmmi-10">&#x00A0;cx</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;t</span>.
<p class="noindent"> It is worth noting that the explicit type signatures provided by Haskell are not powerful enough to express types that
include monomorphic type variables. For example, we cannot write
<div class="quote">
<div class="verbatim" id="verbatim-68">
&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;=&#x00A0;let
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;g&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;b&#x00A0;-&#x003E;&#x00A0;([a],b)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;g&#x00A0;y&#x00A0;z&#x00A0;=&#x00A0;([x,y],&#x00A0;z)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;in&#x00A0;...
</div>
<p class="noindent"></div>
<p class="noindent"> because that would claim that <span
class="pcrr7t-">g</span> was polymorphic in both <span
class="pcrr7t-">a</span> and <span
class="pcrr7t-">b</span> (Section&#x00A0;<a
href="#x10-810004.4.1">4.4.1<!--tex4ht:ref: type-signatures --></a>). In this program, <span
class="pcrr7t-">g</span> can only be
given a type signature if its first argument is restricted to a type not involving type variables; for example
<div class="quote">
<div class="verbatim" id="verbatim-69">
&#x00A0;&#x00A0;g&#x00A0;::&#x00A0;Int&#x00A0;-&#x003E;&#x00A0;b&#x00A0;-&#x003E;&#x00A0;([Int],b)
</div>
<p class="noindent"></div>
<p class="noindent"> This signature would also cause <span
class="pcrr7t-">x</span> to have type <span
class="pcrr7t-">Int</span>.
<p class="noindent">
<h4 class="subsectionHead"><span class="titlemark">4.5.5 </span> <a
id="x10-930004.5.5"></a>The Monomorphism Restriction</h4>
<a
id="dx10-93001"></a>
<p class="noindent"> Haskell places certain extra restrictions on the generalization step, beyond the standard Hindley-Milner restriction
described above, which further reduces polymorphism in particular cases.
<p class="noindent"> The monomorphism restriction depends on the binding syntax of a variable. Recall that a variable is bound by either
a <span
class="ptmri7t-">function binding </span>or a <span
class="ptmri7t-">pattern binding</span>, and that a <span
class="ptmri7t-">simple </span>pattern binding is a pattern binding in which the pattern
consists of only a single variable (Section&#x00A0;<a
href="#x10-830004.4.3">4.4.3<!--tex4ht:ref: pattern-bindings --></a>).
<p class="noindent"> The following two rules define the monomorphism restriction:
<div class="center"
>
<p class="noindent">
<div class="fbox"><div class="minipage"><p class="noindent"> <span class="likeparagraphHead"><a
id="x10-940004.5.5"></a>The monomorphism restriction</span>
<dl class="description"><dt class="description">
<span
class="ptmb7t-">Rule 1.</span> </dt><dd
class="description">We say that a given declaration group is <span
class="ptmri7t-">unrestricted </span>if and only if:
<dl class="description"><dt class="description">
<span
class="ptmb7t-">(a):</span> </dt><dd
class="description">every variable in the group is bound by a function binding or a simple pattern binding<a
id="dx10-94001"></a>
(Section&#x00A0;<a
href="#x10-860004.4.3.2">4.4.3.2<!--tex4ht:ref: patbind --></a>), <span
class="ptmri7t-">and</span>
</dd><dt class="description">
<span
class="ptmb7t-">(b):</span> </dt><dd
class="description">an explicit type signature is given for every variable in the group that is bound by simple
pattern binding.</dd></dl>
<p class="noindent"> The usual Hindley-Milner restriction on polymorphism is that only type variables that do not
occur free in the environment may be generalized. In addition, <span
class="ptmri7t-">the constrained type variables</span>
<span
class="ptmri7t-">of a restricted declaration group may not be generalized </span>in the generalization step for that
group. (Recall that a type variable is constrained if it must belong to some type class; see
Section&#x00A0;<a
href="#x10-900004.5.2">4.5.2<!--tex4ht:ref: generalization --></a>.)
</dd><dt class="description">
<span
class="ptmb7t-">Rule 2.</span> </dt><dd
class="description">Any monomorphic type variables that remain when type inference for an entire module is complete,
are considered <span
class="ptmri7t-">ambiguous</span><a
id="dx10-94002"></a>, and are resolved to particular types using the defaulting rules
(Section&#x00A0;<a
href="#x10-790004.3.4">4.3.4<!--tex4ht:ref: default-decls --></a>).</dd></dl> </div></div>
</div>
<p class="noindent"> <span class="likeparagraphHead"><a
id="x10-950004.5.5"></a>Motivation</span>
Rule 1 is required for two reasons, both of which are fairly subtle.
<ul class="itemize1">
<li class="itemize"><span
class="ptmri7t-">Rule 1 prevents computations from being unexpectedly repeated. </span>For example, <span
class="pcrr7t-">genericLength</span> is a standard
function (in library <span
class="pcrr7t-">Data.List</span>) whose type is given by
<div class="quote">
<div class="verbatim" id="verbatim-70">
&#x00A0;&#x00A0;genericLength&#x00A0;::&#x00A0;Num&#x00A0;a&#x00A0;=&#x003E;&#x00A0;[b]&#x00A0;-&#x003E;&#x00A0;a
</div>
<p class="noindent"></div>
<p class="noindent"> Now consider the following expression:
<div class="quote">
<div class="verbatim" id="verbatim-71">
&#x00A0;&#x00A0;let&#x00A0;{&#x00A0;len&#x00A0;=&#x00A0;genericLength&#x00A0;xs&#x00A0;}&#x00A0;in&#x00A0;(len,&#x00A0;len)
</div>
<p class="noindent"></div>
<p class="noindent"> It looks as if <span
class="pcrr7t-">len</span> should be computed only once, but without Rule&#x00A0;1 it might be computed twice, once at each
of two different overloadings. If the programmer does actually wish the computation to be repeated, an explicit
type signature may be added:
<div class="quote">
<div class="verbatim" id="verbatim-72">
&#x00A0;&#x00A0;let&#x00A0;{&#x00A0;len&#x00A0;::&#x00A0;Num&#x00A0;a&#x00A0;=&#x003E;&#x00A0;a;&#x00A0;len&#x00A0;=&#x00A0;genericLength&#x00A0;xs&#x00A0;}&#x00A0;in&#x00A0;(len,&#x00A0;len)
</div>
<p class="noindent"></div>
</li>
<li class="itemize"><span
class="ptmri7t-">Rule</span><span
class="ptmri7t-">&#x00A0;1 prevents ambiguity. </span>For example, consider the declaration group
<div class="quote">
<div class="verbatim" id="verbatim-73">
&#x00A0;&#x00A0;[(n,s)]&#x00A0;=&#x00A0;reads&#x00A0;t
</div>
<p class="noindent"></div>
<p class="noindent"> Recall that <span
class="pcrr7t-">reads</span> is a standard function whose type is given by the signature
<div class="quote">
<div class="verbatim" id="verbatim-74">
&#x00A0;&#x00A0;reads&#x00A0;::&#x00A0;(Read&#x00A0;a)&#x00A0;=&#x003E;&#x00A0;String&#x00A0;-&#x003E;&#x00A0;[(a,String)]
</div>
<p class="noindent"></div>
<p class="noindent"> Without Rule&#x00A0;1, <span
class="pcrr7t-">n</span> would be assigned the type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span><span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">Read</span><span
class="cmmi-10">&#x00A0;a</span><span
class="cmmi-10">&#x00A0; </span><span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;a</span> and <span
class="pcrr7t-">s</span> the type <span
class="cmsy-10">&forall;</span><span
class="cmmi-10">&#x00A0;a.</span> <span
class="pcrr7t-">Read</span><span
class="cmmi-10">&#x00A0;a</span>
<span
class="cmsy-10">&rArr;</span> <span
class="cmmi-10">&#x00A0;</span><span
class="pcrr7t-">String</span>. The latter is an invalid type, because it is inherently ambiguous. It is not possible to determine at
what overloading to use <span
class="pcrr7t-">s</span>, nor can this be solved by adding a type signature for <span
class="pcrr7t-">s</span>. Hence, when <span
class="ptmri7t-">non-simple</span>
pattern bindings<a
id="dx10-95001"></a> are used (Section&#x00A0;<a
href="#x10-860004.4.3.2">4.4.3.2<!--tex4ht:ref: patbind --></a>), the types inferred are always monomorphic in their constrained
type variables, irrespective of whether a type signature is provided. In this case, both <span
class="pcrr7t-">n</span> and <span
class="pcrr7t-">s</span> are monomorphic
in <span
class="cmmi-10">a</span>.
<p class="noindent"> The same constraint applies to pattern-bound functions. For example, in
<div class="quote">
<div class="verbatim" id="verbatim-75">
&#x00A0;&#x00A0;(f,g)&#x00A0;=&#x00A0;((+),(-))
</div>
<p class="noindent"></div>
<p class="noindent"> both <span
class="pcrr7t-">f</span> and <span
class="pcrr7t-">g</span> are monomorphic regardless of any type signatures supplied for <span
class="pcrr7t-">f</span> or <span
class="pcrr7t-">g</span>.</li></ul>
<p class="noindent"> Rule&#x00A0;2 is required because there is no way to enforce monomorphic use of an <span
class="ptmri7t-">exported </span>binding, except by
performing type inference on modules outside the current module. Rule&#x00A0;2 states that the exact types of all the
variables bound in a module must be determined by that module alone, and not by any modules that import it.
<div class="quote">
<div class="verbatim" id="verbatim-76">
&#x00A0;&#x00A0;module&#x00A0;M1(len1)&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;default(&#x00A0;Int,&#x00A0;Double&#x00A0;)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;len1&#x00A0;=&#x00A0;genericLength&#x00A0;"Hello"
&#x00A0;<br />
&#x00A0;<br />&#x00A0;&#x00A0;module&#x00A0;M2&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;import&#x00A0;M1(len1)
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;len2&#x00A0;=&#x00A0;(2&#x22C6;len1)&#x00A0;::&#x00A0;Rational
</div>
<p class="noindent"></div>
<p class="noindent"> When type inference on module <span
class="pcrr7t-">M1</span> is complete, <span
class="pcrr7t-">len1</span> has the monomorphic type <span
class="pcrr7t-">Num</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;=&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span> (by Rule 1). Rule
2 now states that the monomorphic type variable <span
class="pcrr7t-">a</span> is ambiguous, and must be resolved using the defaulting rules of
Section&#x00A0;<a
href="#x10-790004.3.4">4.3.4<!--tex4ht:ref: default-decls --></a>. Hence, <span
class="pcrr7t-">len1</span> gets type <span
class="pcrr7t-">Int</span>, and its use in <span
class="pcrr7t-">len2</span> is type-incorrect. (If the above code is actually what
is wanted, a type signature on <span
class="pcrr7t-">len1</span> would solve the problem.)
<p class="noindent"> This issue does not arise for nested bindings, because their entire scope is visible to the compiler.
<p class="noindent"> <span class="likeparagraphHead"><a
id="x10-960004.5.5"></a>Consequences</span>
The monomorphism rule has a number of consequences for the programmer. Anything defined with function syntax
usually generalizes as a function is expected to. Thus in
<div class="quote">
<div class="verbatim" id="verbatim-77">
&#x00A0;&#x00A0;f&#x00A0;x&#x00A0;y&#x00A0;=&#x00A0;x+y
</div>
<p class="noindent"></div>
<p class="noindent"> the function <span
class="pcrr7t-">f</span> may be used at any overloading in class <span
class="pcrr7t-">Num</span>. There is no danger of recomputation here. However, the
same function defined with pattern syntax:
<div class="quote">
<div class="verbatim" id="verbatim-78">
&#x00A0;&#x00A0;f&#x00A0;=&#x00A0;\x&#x00A0;-&#x003E;&#x00A0;\y&#x00A0;-&#x003E;&#x00A0;x+y
</div>
<p class="noindent"></div>
<p class="noindent"> requires a type signature if <span
class="pcrr7t-">f</span> is to be fully overloaded. Many functions are most naturally defined using simple
pattern bindings; the user must be careful to affix these with type signatures to retain full overloading. The standard
prelude contains many examples of this:
<div class="quote">
<div class="verbatim" id="verbatim-79">
&#x00A0;&#x00A0;sum&#x00A0;&#x00A0;::&#x00A0;(Num&#x00A0;a)&#x00A0;=&#x003E;&#x00A0;[a]&#x00A0;-&#x003E;&#x00A0;a
&#x00A0;<br />&#x00A0;&#x00A0;sum&#x00A0;&#x00A0;=&#x00A0;&#x00A0;foldl&#x00A0;(+)&#x00A0;0&#x00A0;&#x00A0;
</div>
<p class="noindent"></div>
<p class="noindent"> Rule&#x00A0;1 applies to both top-level and nested definitions. Consider
<div class="quote">
<div class="verbatim" id="verbatim-80">
&#x00A0;&#x00A0;module&#x00A0;M&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;len1&#x00A0;=&#x00A0;genericLength&#x00A0;"Hello"
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;len2&#x00A0;=&#x00A0;(2&#x22C6;len1)&#x00A0;::&#x00A0;Rational
</div>
<p class="noindent"></div>
<p class="noindent"> Here, type inference finds that <span
class="pcrr7t-">len1</span> has the monomorphic type (<span
class="pcrr7t-">Num</span><span
class="pcrr7t-">&#x00A0;a</span><span
class="pcrr7t-">&#x00A0;=&#x003E;</span><span
class="pcrr7t-">&#x00A0;a</span>); and the type variable <span
class="pcrr7t-">a</span> is resolved
to <span
class="pcrr7t-">Rational</span> when performing type inference on <span
class="pcrr7t-">len2</span>.
<p class="noindent">
<h3 class="sectionHead"><span class="titlemark">4.6 </span> <a
id="x10-970004.6"></a>Kind Inference</h3>
<a
id="dx10-97001"></a>
<a
id="dx10-97002"></a>
<p class="noindent"> This section describes the rules that are used to perform <span
class="ptmri7t-">kind inference</span>, i.e. to calculate a suitable kind for each type
constructor and class appearing in a given program.
<p class="noindent"> The first step in the kind inference process is to arrange the set of datatype, synonym, and class definitions into
dependency groups. This can be achieved in much the same way as the dependency analysis for value declarations
that was described in Section&#x00A0;<a
href="#x10-880004.5">4.5<!--tex4ht:ref: dependencyanalysis --></a>. For example, the following program fragment includes the definition of a datatype
constructor <span
class="pcrr7t-">D</span>, a synonym <span
class="pcrr7t-">S</span> and a class <span
class="pcrr7t-">C</span>, all of which would be included in the same dependency group:
<div class="quote">
<div class="verbatim" id="verbatim-81">
&#x00A0;&#x00A0;data&#x00A0;C&#x00A0;a&#x00A0;=&#x003E;&#x00A0;D&#x00A0;a&#x00A0;=&#x00A0;Foo&#x00A0;(S&#x00A0;a)
&#x00A0;<br />&#x00A0;&#x00A0;type&#x00A0;S&#x00A0;a&#x00A0;=&#x00A0;[D&#x00A0;a]
&#x00A0;<br />&#x00A0;&#x00A0;class&#x00A0;C&#x00A0;a&#x00A0;where
&#x00A0;<br />&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;bar&#x00A0;::&#x00A0;a&#x00A0;-&#x003E;&#x00A0;D&#x00A0;a&#x00A0;-&#x003E;&#x00A0;Bool
</div>
<p class="noindent"></div>
<p class="noindent"> The kinds of variables, constructors, and classes within each group are determined using standard techniques of type
inference and kind-preserving unification <span class="cite">[<a
href="haskellli3.html#Xjones:cclasses">8</a>]</span>. For example, in the definitions above, the parameter <span
class="pcrr7t-">a</span> appears
as an argument of the function constructor <span
class="pcrr7t-">(-&#x003E;)</span> in the type of <span
class="pcrr7t-">bar</span> and hence must have kind <span
class="cmsy-10">&lowast;</span>. It
follows that both <span
class="pcrr7t-">D</span> and <span
class="pcrr7t-">S</span> must have kind <span
class="cmsy-10">&lowast;&rarr;&lowast; </span>and that every instance of class <span
class="pcrr7t-">C</span> must have kind
<span
class="cmsy-10">&lowast;</span>.
<p class="noindent"> It is possible that some parts of an inferred kind may not be fully determined by the corresponding definitions; in
such cases, a default of <span
class="cmsy-10">&lowast; </span>is assumed. For example, we could assume an arbitrary kind <span
class="cmmi-10">&kappa; </span>for the <span
class="pcrr7t-">a</span> parameter in each
of the following examples:
<div class="quote">
<div class="verbatim" id="verbatim-82">
&#x00A0;&#x00A0;data&#x00A0;App&#x00A0;f&#x00A0;a&#x00A0;=&#x00A0;A&#x00A0;(f&#x00A0;a)
&#x00A0;<br />&#x00A0;&#x00A0;data&#x00A0;Tree&#x00A0;a&#x00A0;&#x00A0;=&#x00A0;Leaf&#x00A0;|&#x00A0;Fork&#x00A0;(Tree&#x00A0;a)&#x00A0;(Tree&#x00A0;a)
</div>
<p class="noindent"></div>
<p class="noindent"> This would give kinds <span
class="cmr-10">(</span><span
class="cmmi-10">&kappa; </span><span
class="cmsy-10">&rarr;&lowast;</span><span
class="cmr-10">) </span><span
class="cmsy-10">&rarr; </span><span
class="cmmi-10">&kappa; </span><span
class="cmsy-10">&rarr;&lowast; </span>and <span
class="cmmi-10">&kappa; </span><span
class="cmsy-10">&rarr;&lowast; </span>for <span
class="pcrr7t-">App</span> and <span
class="pcrr7t-">Tree</span>, respectively, for any kind <span
class="cmmi-10">&kappa;</span>, and would
require an extension to allow polymorphic kinds. Instead, using the default binding <span
class="cmmi-10">&kappa; </span><span
class="cmr-10">= </span><span
class="cmsy-10">&lowast;</span>, the actual kinds for these
two constructors are <span
class="cmr-10">(</span><span
class="cmsy-10">&lowast;&rarr;&lowast;</span><span
class="cmr-10">) </span><span
class="cmsy-10">&rarr;&lowast;&rarr;&lowast; </span>and <span
class="cmsy-10">&lowast;&rarr;&lowast;</span>, respectively.
<p class="noindent"> Defaults are applied to each dependency group without consideration of the ways in which particular type
constructor constants or classes are used in later dependency groups or elsewhere in the program. For example,
adding the following definition to those above does not influence the kind inferred for <span
class="pcrr7t-">Tree</span> (by changing it to
<span
class="cmr-10">(</span><span
class="cmsy-10">&lowast;&rarr;&lowast;</span><span
class="cmr-10">) </span><span
class="cmsy-10">&rarr;&lowast;</span>, for instance), and instead generates a static error because the kind of <span
class="pcrr7t-">[]</span>, <span
class="cmsy-10">&lowast;&rarr;&lowast;</span>, does not match the
kind <span
class="cmsy-10">&lowast; </span>that is expected for an argument of <span
class="pcrr7t-">Tree</span>:
<div class="quote">
<div class="verbatim" id="verbatim-83">
&#x00A0;&#x00A0;type&#x00A0;FunnyTree&#x00A0;=&#x00A0;Tree&#x00A0;[]&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;--&#x00A0;invalid
</div>
<p class="noindent"></div>
<p class="noindent"> This is important because it ensures that each constructor and class are used consistently with the same kind
whenever they are in scope.
<!--l. 7--><div class="crosslinks"><p class="noindent">[<a
href="haskellch5.html" >next</a>] [<a
href="haskellch3.html" >prev</a>] [<a
href="haskellch3.html#tailhaskellch3.html" >prev-tail</a>] [<a
href="haskellch4.html" >front</a>] [<a
href="haskellpa1.html#haskellch4.html" >up</a>] </p></div>
<p class="noindent"> <a
id="tailhaskellch4.html"></a>
</body></html>