Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 8d1ef08c9e0d44c69764afc615a03d0d > files > 1611

ghc-ghc-devel-6.12.3-5.fc14.i686.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ -->
<title>iface/BuildTyCl.lhs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
%
% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>BuildTyCl</span> <span class='hs-layout'>(</span>
<a name="line-2"></a>	<span class='hs-varid'>buildSynTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>buildAlgTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>buildDataCon</span><span class='hs-layout'>,</span>
<a name="line-3"></a>	<span class='hs-varid'>buildClass</span><span class='hs-layout'>,</span>
<a name="line-4"></a>	<span class='hs-varid'>mkAbstractTyConRhs</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkOpenDataTyConRhs</span><span class='hs-layout'>,</span> 
<a name="line-5"></a>	<span class='hs-varid'>mkNewTyConRhs</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkDataTyConRhs</span><span class='hs-layout'>,</span> <span class='hs-varid'>setAssocFamilyPermutation</span>
<a name="line-6"></a>    <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-7"></a>
<a name="line-8"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-9"></a>
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>IfaceEnv</span>
<a name="line-11"></a>
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>DataCon</span>
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Var</span>
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>VarSet</span>
<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BasicTypes</span>
<a name="line-16"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Name</span>
<a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>MkId</span>
<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Class</span>
<a name="line-19"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TyCon</span>
<a name="line-20"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span>
<a name="line-21"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Coercion</span>
<a name="line-22"></a>
<a name="line-23"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TcRnMonad</span>
<a name="line-24"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Util</span>		<span class='hs-layout'>(</span> <span class='hs-varid'>count</span> <span class='hs-layout'>)</span>
<a name="line-25"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span>
</pre>\end{code}
	

\begin{code}
<pre><a name="line-1"></a><a name="buildSynTyCon"></a><span class='hs-comment'>------------------------------------------------------</span>
<a name="line-2"></a><span class='hs-definition'>buildSynTyCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> 
<a name="line-3"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>SynTyConRhs</span> 
<a name="line-4"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Kind</span>			<span class='hs-comment'>-- Kind of the RHS</span>
<a name="line-5"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyCon</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>  <span class='hs-comment'>-- family instance if applicable</span>
<a name="line-6"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TcRnIf</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-conid'>TyCon</span>
<a name="line-7"></a>
<a name="line-8"></a><span class='hs-definition'>buildSynTyCon</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>rhs</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>OpenSynTyCon</span> <span class='hs-layout'>{</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs_kind</span> <span class='hs-keyword'>_</span>
<a name="line-9"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span>
<a name="line-10"></a>      <span class='hs-varid'>kind</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkArrowKinds</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>tyVarKind</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs_kind</span>
<a name="line-11"></a>    <span class='hs-keyword'>in</span>
<a name="line-12"></a>    <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkSynTyCon</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>kind</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>rhs</span> <span class='hs-conid'>NoParentTyCon</span>
<a name="line-13"></a>    
<a name="line-14"></a><span class='hs-definition'>buildSynTyCon</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>rhs</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>SynonymTyCon</span> <span class='hs-layout'>{</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs_kind</span> <span class='hs-varid'>mb_family</span>
<a name="line-15"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span> <span class='hs-comment'>-- We need to tie a knot as the coercion of a data instance depends</span>
<a name="line-16"></a>	 <span class='hs-comment'>-- on the instance representation tycon and vice versa.</span>
<a name="line-17"></a>       <span class='hs-layout'>;</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>fixM</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>tycon_rec</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span> 
<a name="line-18"></a>	 <span class='hs-layout'>{</span> <span class='hs-varid'>parent</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>mkParentInfo</span> <span class='hs-varid'>mb_family</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>tycon_rec</span>
<a name="line-19"></a>	 <span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>{</span> <span class='hs-varid'>tycon</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkSynTyCon</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>kind</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>rhs</span> <span class='hs-varid'>parent</span>
<a name="line-20"></a>	       <span class='hs-layout'>;</span> <span class='hs-varid'>kind</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkArrowKinds</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>tyVarKind</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs_kind</span>
<a name="line-21"></a>	       <span class='hs-layout'>}</span>
<a name="line-22"></a>         <span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>tycon</span>
<a name="line-23"></a>         <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-24"></a>       <span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>tycon</span> 
<a name="line-25"></a>       <span class='hs-layout'>}</span>
<a name="line-26"></a>
<a name="line-27"></a><a name="buildAlgTyCon"></a><span class='hs-comment'>------------------------------------------------------</span>
<a name="line-28"></a><span class='hs-definition'>buildAlgTyCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> 
<a name="line-29"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ThetaType</span>		<span class='hs-comment'>-- Stupid theta</span>
<a name="line-30"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>AlgTyConRhs</span>
<a name="line-31"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RecFlag</span>
<a name="line-32"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>			<span class='hs-comment'>-- True &lt;=&gt; want generics functions</span>
<a name="line-33"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>			<span class='hs-comment'>-- True &lt;=&gt; was declared in GADT syntax</span>
<a name="line-34"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyCon</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>  <span class='hs-comment'>-- family instance if applicable</span>
<a name="line-35"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TcRnIf</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-conid'>TyCon</span>
<a name="line-36"></a>
<a name="line-37"></a><span class='hs-definition'>buildAlgTyCon</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>stupid_theta</span> <span class='hs-varid'>rhs</span> <span class='hs-varid'>is_rec</span> <span class='hs-varid'>want_generics</span> <span class='hs-varid'>gadt_syn</span>
<a name="line-38"></a>	      <span class='hs-varid'>mb_family</span>
<a name="line-39"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span> <span class='hs-comment'>-- We need to tie a knot as the coercion of a data instance depends</span>
<a name="line-40"></a>	 <span class='hs-comment'>-- on the instance representation tycon and vice versa.</span>
<a name="line-41"></a>       <span class='hs-layout'>;</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>fixM</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>tycon_rec</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span> 
<a name="line-42"></a>	 <span class='hs-layout'>{</span> <span class='hs-varid'>parent</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>mkParentInfo</span> <span class='hs-varid'>mb_family</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>tycon_rec</span>
<a name="line-43"></a>	 <span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>{</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkAlgTyCon</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>kind</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>stupid_theta</span> <span class='hs-varid'>rhs</span>
<a name="line-44"></a>				    <span class='hs-varid'>parent</span> <span class='hs-varid'>is_rec</span> <span class='hs-varid'>want_generics</span> <span class='hs-varid'>gadt_syn</span>
<a name="line-45"></a>	       <span class='hs-layout'>;</span> <span class='hs-varid'>kind</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkArrowKinds</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>tyVarKind</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>liftedTypeKind</span>
<a name="line-46"></a>	       <span class='hs-layout'>}</span>
<a name="line-47"></a>         <span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>tycon</span>
<a name="line-48"></a>         <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-49"></a>       <span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>tycon</span> 
<a name="line-50"></a>       <span class='hs-layout'>}</span>
<a name="line-51"></a>
<a name="line-52"></a><a name="mkParentInfo"></a><span class='hs-comment'>-- If a family tycon with instance types is given, the current tycon is an</span>
<a name="line-53"></a><span class='hs-comment'>-- instance of that family and we need to</span>
<a name="line-54"></a><span class='hs-comment'>--</span>
<a name="line-55"></a><span class='hs-comment'>-- (1) create a coercion that identifies the family instance type and the</span>
<a name="line-56"></a><span class='hs-comment'>--     representation type from Step (1); ie, it is of the form </span>
<a name="line-57"></a><span class='hs-comment'>--	   `Co tvs :: F ts ~ R tvs', where `Co' is the name of the coercion,</span>
<a name="line-58"></a><span class='hs-comment'>--	   `F' the family tycon and `R' the (derived) representation tycon,</span>
<a name="line-59"></a><span class='hs-comment'>--	   and</span>
<a name="line-60"></a><span class='hs-comment'>-- (2) produce a `TyConParent' value containing the parent and coercion</span>
<a name="line-61"></a><span class='hs-comment'>--     information.</span>
<a name="line-62"></a><span class='hs-comment'>--</span>
<a name="line-63"></a><span class='hs-definition'>mkParentInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyCon</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> 
<a name="line-64"></a>             <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> 
<a name="line-65"></a>             <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span> 
<a name="line-66"></a>             <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TcRnIf</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-conid'>TyConParent</span>
<a name="line-67"></a><span class='hs-definition'>mkParentInfo</span> <span class='hs-conid'>Nothing</span>                  <span class='hs-keyword'>_</span>       <span class='hs-keyword'>_</span>   <span class='hs-keyword'>_</span>         <span class='hs-keyglyph'>=</span>
<a name="line-68"></a>  <span class='hs-varid'>return</span> <span class='hs-conid'>NoParentTyCon</span>
<a name="line-69"></a><span class='hs-definition'>mkParentInfo</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>family</span><span class='hs-layout'>,</span> <span class='hs-varid'>instTys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>rep_tycon</span> <span class='hs-keyglyph'>=</span>
<a name="line-70"></a>  <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span> <span class='hs-comment'>-- Create the coercion</span>
<a name="line-71"></a>     <span class='hs-layout'>;</span> <span class='hs-varid'>co_tycon_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>tc_name</span> <span class='hs-varid'>mkInstTyCoOcc</span>
<a name="line-72"></a>     <span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>co_tycon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkFamInstCoercion</span> <span class='hs-varid'>co_tycon_name</span> <span class='hs-varid'>tvs</span>
<a name="line-73"></a>                                        <span class='hs-varid'>family</span> <span class='hs-varid'>instTys</span> <span class='hs-varid'>rep_tycon</span>
<a name="line-74"></a>     <span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>FamilyTyCon</span> <span class='hs-varid'>family</span> <span class='hs-varid'>instTys</span> <span class='hs-varid'>co_tycon</span>
<a name="line-75"></a>     <span class='hs-layout'>}</span>
<a name="line-76"></a>    
<a name="line-77"></a><a name="mkAbstractTyConRhs"></a><span class='hs-comment'>------------------------------------------------------</span>
<a name="line-78"></a><span class='hs-definition'>mkAbstractTyConRhs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AlgTyConRhs</span>
<a name="line-79"></a><span class='hs-definition'>mkAbstractTyConRhs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AbstractTyCon</span>
<a name="line-80"></a>
<a name="line-81"></a><a name="mkOpenDataTyConRhs"></a><span class='hs-definition'>mkOpenDataTyConRhs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AlgTyConRhs</span>
<a name="line-82"></a><span class='hs-definition'>mkOpenDataTyConRhs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>OpenTyCon</span> <span class='hs-conid'>Nothing</span>
<a name="line-83"></a>
<a name="line-84"></a><a name="mkDataTyConRhs"></a><span class='hs-definition'>mkDataTyConRhs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>DataCon</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>AlgTyConRhs</span>
<a name="line-85"></a><span class='hs-definition'>mkDataTyConRhs</span> <span class='hs-varid'>cons</span>
<a name="line-86"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>DataTyCon</span> <span class='hs-layout'>{</span>
<a name="line-87"></a>        <span class='hs-varid'>data_cons</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cons</span><span class='hs-layout'>,</span>
<a name="line-88"></a>        <span class='hs-varid'>is_enum</span> <span class='hs-keyglyph'>=</span> <span class='hs-comment'>-- We define datatypes with no constructors to not be</span>
<a name="line-89"></a>                  <span class='hs-comment'>-- enumerations; this fixes trac #2578</span>
<a name="line-90"></a>                  <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>cons</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span>
<a name="line-91"></a>                  <span class='hs-varid'>all</span> <span class='hs-varid'>isNullarySrcDataCon</span> <span class='hs-varid'>cons</span>
<a name="line-92"></a>    <span class='hs-layout'>}</span>
<a name="line-93"></a>
<a name="line-94"></a><a name="mkNewTyConRhs"></a><span class='hs-definition'>mkNewTyConRhs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>DataCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TcRnIf</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-conid'>AlgTyConRhs</span>
<a name="line-95"></a><span class='hs-comment'>-- Monadic because it makes a Name for the coercion TyCon</span>
<a name="line-96"></a><span class='hs-comment'>-- We pass the Name of the parent TyCon, as well as the TyCon itself,</span>
<a name="line-97"></a><span class='hs-comment'>-- because the latter is part of a knot, whereas the former is not.</span>
<a name="line-98"></a><span class='hs-definition'>mkNewTyConRhs</span> <span class='hs-varid'>tycon_name</span> <span class='hs-varid'>tycon</span> <span class='hs-varid'>con</span> 
<a name="line-99"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-varid'>co_tycon_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>tycon_name</span> <span class='hs-varid'>mkNewTyCoOcc</span>
<a name="line-100"></a>	<span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>co_tycon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkNewTypeCoercion</span> <span class='hs-varid'>co_tycon_name</span> <span class='hs-varid'>tycon</span> <span class='hs-varid'>etad_tvs</span> <span class='hs-varid'>etad_rhs</span>
<a name="line-101"></a>              <span class='hs-varid'>cocon_maybe</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>all_coercions</span> <span class='hs-varop'>||</span> <span class='hs-varid'>isRecursiveTyCon</span> <span class='hs-varid'>tycon</span> 
<a name="line-102"></a>		          <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>co_tycon</span>
<a name="line-103"></a>                	  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>              
<a name="line-104"></a>                	  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-105"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>traceIf</span> <span class='hs-layout'>(</span><span class='hs-varid'>text</span> <span class='hs-str'>"mkNewTyConRhs"</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>cocon_maybe</span><span class='hs-layout'>)</span>
<a name="line-106"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-conid'>NewTyCon</span> <span class='hs-layout'>{</span> <span class='hs-varid'>data_con</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>con</span><span class='hs-layout'>,</span> 
<a name="line-107"></a>		       	     <span class='hs-varid'>nt_rhs</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rhs_ty</span><span class='hs-layout'>,</span>
<a name="line-108"></a>		       	     <span class='hs-varid'>nt_etad_rhs</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>etad_tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>etad_rhs</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-109"></a> 		       	     <span class='hs-varid'>nt_co</span> 	 <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cocon_maybe</span> <span class='hs-layout'>}</span> <span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-110"></a>                             <span class='hs-comment'>-- Coreview looks through newtypes with a Nothing</span>
<a name="line-111"></a>                             <span class='hs-comment'>-- for nt_co, or uses explicit coercions otherwise</span>
<a name="line-112"></a>  <span class='hs-keyword'>where</span>
<a name="line-113"></a>        <span class='hs-comment'>-- If all_coercions is True then we use coercions for all newtypes</span>
<a name="line-114"></a>        <span class='hs-comment'>-- otherwise we use coercions for recursive newtypes and look through</span>
<a name="line-115"></a>        <span class='hs-comment'>-- non-recursive newtypes</span>
<a name="line-116"></a>    <span class='hs-varid'>all_coercions</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-117"></a>    <span class='hs-varid'>tvs</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyConTyVars</span> <span class='hs-varid'>tycon</span>
<a name="line-118"></a>    <span class='hs-varid'>inst_con_ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>applyTys</span> <span class='hs-layout'>(</span><span class='hs-varid'>dataConUserType</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkTyVarTys</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span>
<a name="line-119"></a>    <span class='hs-varid'>rhs_ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>isFunTy</span> <span class='hs-varid'>inst_con_ty</span> <span class='hs-layout'>)</span> <span class='hs-varid'>funArgTy</span> <span class='hs-varid'>inst_con_ty</span>
<a name="line-120"></a>	<span class='hs-comment'>-- Instantiate the data con with the </span>
<a name="line-121"></a>	<span class='hs-comment'>-- type variables from the tycon</span>
<a name="line-122"></a>	<span class='hs-comment'>-- NB: a newtype DataCon has a type that must look like</span>
<a name="line-123"></a>	<span class='hs-comment'>--        forall tvs.  &lt;arg-ty&gt; -&gt; T tvs</span>
<a name="line-124"></a>	<span class='hs-comment'>-- Note that we *can't* use dataConInstOrigArgTys here because</span>
<a name="line-125"></a>	<span class='hs-comment'>-- the newtype arising from   class Foo a =&gt; Bar a where {}</span>
<a name="line-126"></a>  	<span class='hs-comment'>-- has a single argument (Foo a) that is a *type class*, so</span>
<a name="line-127"></a>	<span class='hs-comment'>-- dataConInstOrigArgTys returns [].</span>
<a name="line-128"></a>
<a name="line-129"></a>    <span class='hs-varid'>etad_tvs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span>	<span class='hs-comment'>-- Matched lazily, so that mkNewTypeCoercion can</span>
<a name="line-130"></a>    <span class='hs-varid'>etad_rhs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span>	<span class='hs-comment'>-- return a TyCon without pulling on rhs_ty</span>
<a name="line-131"></a>			<span class='hs-comment'>-- See Note [Tricky iface loop] in LoadIface</span>
<a name="line-132"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>etad_tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>etad_rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>eta_reduce</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs_ty</span>
<a name="line-133"></a> 
<a name="line-134"></a>    <span class='hs-varid'>eta_reduce</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span>		<span class='hs-comment'>-- Reversed</span>
<a name="line-135"></a>	       <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span>			<span class='hs-comment'>-- Rhs type</span>
<a name="line-136"></a>	       <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-conid'>Type</span><span class='hs-layout'>)</span>	<span class='hs-comment'>-- Eta-reduced version (tyvars in normal order)</span>
<a name="line-137"></a>    <span class='hs-varid'>eta_reduce</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-keyword'>as</span><span class='hs-layout'>)</span> <span class='hs-varid'>ty</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>fun</span><span class='hs-layout'>,</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>splitAppTy_maybe</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span>
<a name="line-138"></a>			   <span class='hs-conid'>Just</span> <span class='hs-varid'>tv</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>getTyVar_maybe</span> <span class='hs-varid'>arg</span><span class='hs-layout'>,</span>
<a name="line-139"></a>			   <span class='hs-varid'>tv</span> <span class='hs-varop'>==</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span>
<a name="line-140"></a>			   <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-varop'>`elemVarSet`</span> <span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>fun</span><span class='hs-layout'>)</span>
<a name="line-141"></a>			 <span class='hs-keyglyph'>=</span> <span class='hs-varid'>eta_reduce</span> <span class='hs-keyword'>as</span> <span class='hs-varid'>fun</span>
<a name="line-142"></a>    <span class='hs-varid'>eta_reduce</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-143"></a>				
<a name="line-144"></a>
<a name="line-145"></a><a name="setAssocFamilyPermutation"></a><span class='hs-definition'>setAssocFamilyPermutation</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyThing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyThing</span>
<a name="line-146"></a><span class='hs-definition'>setAssocFamilyPermutation</span> <span class='hs-varid'>clas_tvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>ATyCon</span> <span class='hs-varid'>tc</span><span class='hs-layout'>)</span> 
<a name="line-147"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ATyCon</span> <span class='hs-layout'>(</span><span class='hs-varid'>setTyConArgPoss</span> <span class='hs-varid'>clas_tvs</span> <span class='hs-varid'>tc</span><span class='hs-layout'>)</span>
<a name="line-148"></a><span class='hs-definition'>setAssocFamilyPermutation</span> <span class='hs-sel'>_clas_tvs</span> <span class='hs-varid'>other</span>
<a name="line-149"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>pprPanic</span> <span class='hs-str'>"setAssocFamilyPermutation"</span> <span class='hs-layout'>(</span><span class='hs-varid'>ppr</span> <span class='hs-varid'>other</span><span class='hs-layout'>)</span>
<a name="line-150"></a>
<a name="line-151"></a>
<a name="line-152"></a><a name="buildDataCon"></a><span class='hs-comment'>------------------------------------------------------</span>
<a name="line-153"></a><span class='hs-definition'>buildDataCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-154"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>StrictnessMark</span><span class='hs-keyglyph'>]</span> 
<a name="line-155"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Name</span><span class='hs-keyglyph'>]</span>			<span class='hs-comment'>-- Field labels</span>
<a name="line-156"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span>	<span class='hs-comment'>-- Univ and ext </span>
<a name="line-157"></a>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>TyVar</span><span class='hs-layout'>,</span><span class='hs-conid'>Type</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>           <span class='hs-comment'>-- Equality spec</span>
<a name="line-158"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ThetaType</span>		<span class='hs-comment'>-- Does not include the "stupid theta"</span>
<a name="line-159"></a>					<span class='hs-comment'>-- or the GADT equalities</span>
<a name="line-160"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span>		<span class='hs-comment'>-- Argument and result types</span>
<a name="line-161"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span>			<span class='hs-comment'>-- Rep tycon</span>
<a name="line-162"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TcRnIf</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-conid'>DataCon</span>
<a name="line-163"></a><span class='hs-comment'>-- A wrapper for DataCon.mkDataCon that</span>
<a name="line-164"></a><span class='hs-comment'>--   a) makes the worker Id</span>
<a name="line-165"></a><span class='hs-comment'>--   b) makes the wrapper Id if necessary, including</span>
<a name="line-166"></a><span class='hs-comment'>--	allocating its unique (hence monadic)</span>
<a name="line-167"></a><span class='hs-definition'>buildDataCon</span> <span class='hs-varid'>src_name</span> <span class='hs-varid'>declared_infix</span> <span class='hs-varid'>arg_stricts</span> <span class='hs-varid'>field_lbls</span>
<a name="line-168"></a>	     <span class='hs-varid'>univ_tvs</span> <span class='hs-varid'>ex_tvs</span> <span class='hs-varid'>eq_spec</span> <span class='hs-varid'>ctxt</span> <span class='hs-varid'>arg_tys</span> <span class='hs-varid'>res_ty</span> <span class='hs-varid'>rep_tycon</span>
<a name="line-169"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-varid'>wrap_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>src_name</span> <span class='hs-varid'>mkDataConWrapperOcc</span>
<a name="line-170"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>work_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>src_name</span> <span class='hs-varid'>mkDataConWorkerOcc</span>
<a name="line-171"></a>	<span class='hs-comment'>-- This last one takes the name of the data constructor in the source</span>
<a name="line-172"></a>	<span class='hs-comment'>-- code, which (for Haskell source anyway) will be in the DataName name</span>
<a name="line-173"></a>	<span class='hs-comment'>-- space, and puts it into the VarName name space</span>
<a name="line-174"></a>
<a name="line-175"></a>	<span class='hs-layout'>;</span> <span class='hs-keyword'>let</span>
<a name="line-176"></a>		<span class='hs-varid'>stupid_ctxt</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkDataConStupidTheta</span> <span class='hs-varid'>rep_tycon</span> <span class='hs-varid'>arg_tys</span> <span class='hs-varid'>univ_tvs</span>
<a name="line-177"></a>		<span class='hs-varid'>data_con</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkDataCon</span> <span class='hs-varid'>src_name</span> <span class='hs-varid'>declared_infix</span>
<a name="line-178"></a>				     <span class='hs-varid'>arg_stricts</span> <span class='hs-varid'>field_lbls</span>
<a name="line-179"></a>				     <span class='hs-varid'>univ_tvs</span> <span class='hs-varid'>ex_tvs</span> <span class='hs-varid'>eq_spec</span> <span class='hs-varid'>ctxt</span>
<a name="line-180"></a>				     <span class='hs-varid'>arg_tys</span> <span class='hs-varid'>res_ty</span> <span class='hs-varid'>rep_tycon</span>
<a name="line-181"></a>				     <span class='hs-varid'>stupid_ctxt</span> <span class='hs-varid'>dc_ids</span>
<a name="line-182"></a>		<span class='hs-varid'>dc_ids</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkDataConIds</span> <span class='hs-varid'>wrap_name</span> <span class='hs-varid'>work_name</span> <span class='hs-varid'>data_con</span>
<a name="line-183"></a>
<a name="line-184"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>data_con</span> <span class='hs-layout'>}</span>
<a name="line-185"></a>
<a name="line-186"></a>
<a name="line-187"></a><a name="mkDataConStupidTheta"></a><span class='hs-comment'>-- The stupid context for a data constructor should be limited to</span>
<a name="line-188"></a><span class='hs-comment'>-- the type variables mentioned in the arg_tys</span>
<a name="line-189"></a><span class='hs-comment'>-- ToDo: Or functionally dependent on?  </span>
<a name="line-190"></a><span class='hs-comment'>--	 This whole stupid theta thing is, well, stupid.</span>
<a name="line-191"></a><span class='hs-definition'>mkDataConStupidTheta</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TyCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>PredType</span><span class='hs-keyglyph'>]</span>
<a name="line-192"></a><span class='hs-definition'>mkDataConStupidTheta</span> <span class='hs-varid'>tycon</span> <span class='hs-varid'>arg_tys</span> <span class='hs-varid'>univ_tvs</span>
<a name="line-193"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-varid'>stupid_theta</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>[]</span>	<span class='hs-comment'>-- The common case</span>
<a name="line-194"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> 	      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>filter</span> <span class='hs-varid'>in_arg_tys</span> <span class='hs-varid'>stupid_theta</span>
<a name="line-195"></a>  <span class='hs-keyword'>where</span>
<a name="line-196"></a>    <span class='hs-varid'>tc_subst</span>	 <span class='hs-keyglyph'>=</span> <span class='hs-varid'>zipTopTvSubst</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyConTyVars</span> <span class='hs-varid'>tycon</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkTyVarTys</span> <span class='hs-varid'>univ_tvs</span><span class='hs-layout'>)</span>
<a name="line-197"></a>    <span class='hs-varid'>stupid_theta</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substTheta</span> <span class='hs-varid'>tc_subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyConStupidTheta</span> <span class='hs-varid'>tycon</span><span class='hs-layout'>)</span>
<a name="line-198"></a>	<span class='hs-comment'>-- Start by instantiating the master copy of the </span>
<a name="line-199"></a>	<span class='hs-comment'>-- stupid theta, taken from the TyCon</span>
<a name="line-200"></a>
<a name="line-201"></a>    <span class='hs-varid'>arg_tyvars</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyVarsOfTypes</span> <span class='hs-varid'>arg_tys</span>
<a name="line-202"></a>    <span class='hs-varid'>in_arg_tys</span> <span class='hs-varid'>pred</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>not</span> <span class='hs-varop'>$</span> <span class='hs-varid'>isEmptyVarSet</span> <span class='hs-varop'>$</span> 
<a name="line-203"></a>		      <span class='hs-varid'>tyVarsOfPred</span> <span class='hs-varid'>pred</span> <span class='hs-varop'>`intersectVarSet`</span> <span class='hs-varid'>arg_tyvars</span>
</pre>\end{code}


------------------------------------------------------
\begin{code}
<pre><a name="line-1"></a><a name="buildClass"></a><span class='hs-definition'>buildClass</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span>			<span class='hs-comment'>-- True &lt;=&gt; do not include unfoldings </span>
<a name="line-2"></a>					<span class='hs-comment'>--	    on dict selectors</span>
<a name="line-3"></a>					<span class='hs-comment'>-- Used when importing a class without -O</span>
<a name="line-4"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ThetaType</span>
<a name="line-5"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>FunDep</span> <span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span>		<span class='hs-comment'>-- Functional dependencies</span>
<a name="line-6"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyThing</span><span class='hs-keyglyph'>]</span>			<span class='hs-comment'>-- Associated types</span>
<a name="line-7"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Name</span><span class='hs-layout'>,</span> <span class='hs-conid'>DefMeth</span><span class='hs-layout'>,</span> <span class='hs-conid'>Type</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>	<span class='hs-comment'>-- Method info</span>
<a name="line-8"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RecFlag</span>			<span class='hs-comment'>-- Info for type constructor</span>
<a name="line-9"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TcRnIf</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-conid'>Class</span>
<a name="line-10"></a>
<a name="line-11"></a><span class='hs-definition'>buildClass</span> <span class='hs-varid'>no_unf</span> <span class='hs-varid'>class_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>sc_theta</span> <span class='hs-varid'>fds</span> <span class='hs-varid'>ats</span> <span class='hs-varid'>sig_stuff</span> <span class='hs-varid'>tc_isrec</span>
<a name="line-12"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-varid'>traceIf</span> <span class='hs-layout'>(</span><span class='hs-varid'>text</span> <span class='hs-str'>"buildClass"</span><span class='hs-layout'>)</span>
<a name="line-13"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>tycon_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>class_name</span> <span class='hs-varid'>mkClassTyConOcc</span>
<a name="line-14"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>datacon_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>class_name</span> <span class='hs-varid'>mkClassDataConOcc</span>
<a name="line-15"></a>		<span class='hs-comment'>-- The class name is the 'parent' for this datacon, not its tycon,</span>
<a name="line-16"></a>		<span class='hs-comment'>-- because one should import the class to get the binding for </span>
<a name="line-17"></a>		<span class='hs-comment'>-- the datacon</span>
<a name="line-18"></a>
<a name="line-19"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>fixM</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>rec_clas</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span>	<span class='hs-comment'>-- Only name generation inside loop</span>
<a name="line-20"></a>
<a name="line-21"></a>	  <span class='hs-keyword'>let</span> <span class='hs-layout'>{</span> <span class='hs-varid'>rec_tycon</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>classTyCon</span> <span class='hs-varid'>rec_clas</span>
<a name="line-22"></a>	      <span class='hs-layout'>;</span> <span class='hs-varid'>op_tys</span>	   <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>ty</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>sig_stuff</span><span class='hs-keyglyph'>]</span>
<a name="line-23"></a>	      <span class='hs-layout'>;</span> <span class='hs-varid'>op_names</span>   <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>op</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>op</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>sig_stuff</span><span class='hs-keyglyph'>]</span>
<a name="line-24"></a>	      <span class='hs-layout'>;</span> <span class='hs-varid'>op_items</span>   <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkDictSelId</span> <span class='hs-varid'>no_unf</span> <span class='hs-varid'>op_name</span> <span class='hs-varid'>rec_clas</span><span class='hs-layout'>,</span> <span class='hs-varid'>dm_info</span><span class='hs-layout'>)</span>
<a name="line-25"></a>			     <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>op_name</span><span class='hs-layout'>,</span> <span class='hs-varid'>dm_info</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>sig_stuff</span> <span class='hs-keyglyph'>]</span> <span class='hs-layout'>}</span>
<a name="line-26"></a>	  		<span class='hs-comment'>-- Build the selector id and default method id</span>
<a name="line-27"></a>
<a name="line-28"></a>	<span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>n_value_preds</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>count</span> <span class='hs-layout'>(</span><span class='hs-varid'>not</span> <span class='hs-varop'>.</span> <span class='hs-varid'>isEqPred</span><span class='hs-layout'>)</span> <span class='hs-varid'>sc_theta</span>
<a name="line-29"></a>	      <span class='hs-varid'>all_value_preds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n_value_preds</span> <span class='hs-varop'>==</span> <span class='hs-varid'>length</span> <span class='hs-varid'>sc_theta</span>
<a name="line-30"></a>	      <span class='hs-comment'>-- We only make selectors for the *value* superclasses, </span>
<a name="line-31"></a>	      <span class='hs-comment'>-- not equality predicates </span>
<a name="line-32"></a>
<a name="line-33"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>sc_sel_names</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>mapM</span>  <span class='hs-layout'>(</span><span class='hs-varid'>newImplicitBinder</span> <span class='hs-varid'>class_name</span> <span class='hs-varop'>.</span> <span class='hs-varid'>mkSuperDictSelOcc</span><span class='hs-layout'>)</span> 
<a name="line-34"></a>				<span class='hs-keyglyph'>[</span><span class='hs-num'>1</span><span class='hs-keyglyph'>..</span><span class='hs-varid'>n_value_preds</span><span class='hs-keyglyph'>]</span>
<a name="line-35"></a>        <span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>sc_sel_ids</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>mkDictSelId</span> <span class='hs-varid'>no_unf</span> <span class='hs-varid'>sc_name</span> <span class='hs-varid'>rec_clas</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>sc_name</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>sc_sel_names</span><span class='hs-keyglyph'>]</span>
<a name="line-36"></a>	      <span class='hs-comment'>-- We number off the Dict superclass selectors, 1, 2, 3 etc so that we </span>
<a name="line-37"></a>	      <span class='hs-comment'>-- can construct names for the selectors. Thus</span>
<a name="line-38"></a>	      <span class='hs-comment'>--      class (C a, C b) =&gt; D a b where ...</span>
<a name="line-39"></a>	      <span class='hs-comment'>-- gives superclass selectors</span>
<a name="line-40"></a>	      <span class='hs-comment'>--      D_sc1, D_sc2</span>
<a name="line-41"></a>	      <span class='hs-comment'>-- (We used to call them D_C, but now we can have two different</span>
<a name="line-42"></a>	      <span class='hs-comment'>--  superclasses both called C!)</span>
<a name="line-43"></a>	      <span class='hs-comment'>--</span>
<a name="line-44"></a>	
<a name="line-45"></a>	<span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>use_newtype</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>n_value_preds</span> <span class='hs-varop'>+</span> <span class='hs-varid'>length</span> <span class='hs-varid'>sig_stuff</span> <span class='hs-varop'>==</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>all_value_preds</span>
<a name="line-46"></a>		<span class='hs-comment'>-- Use a newtype if the data constructor has </span>
<a name="line-47"></a>		<span class='hs-comment'>-- 	(a) exactly one value field</span>
<a name="line-48"></a>		<span class='hs-comment'>--	(b) no existential or equality-predicate fields</span>
<a name="line-49"></a>		<span class='hs-comment'>-- i.e. exactly one operation or superclass taken together</span>
<a name="line-50"></a>		<span class='hs-comment'>-- See note [Class newtypes and equality predicates]</span>
<a name="line-51"></a>
<a name="line-52"></a>		<span class='hs-comment'>-- We play a bit fast and loose by treating the superclasses</span>
<a name="line-53"></a>		<span class='hs-comment'>-- as ordinary arguments.  That means that in the case of</span>
<a name="line-54"></a>		<span class='hs-comment'>--     class C a =&gt; D a</span>
<a name="line-55"></a>		<span class='hs-comment'>-- we don't get a newtype with no arguments!</span>
<a name="line-56"></a>	      <span class='hs-varid'>args</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sc_sel_names</span> <span class='hs-varop'>++</span> <span class='hs-varid'>op_names</span>
<a name="line-57"></a>	      <span class='hs-varid'>arg_tys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>mkPredTy</span> <span class='hs-varid'>sc_theta</span> <span class='hs-varop'>++</span> <span class='hs-varid'>op_tys</span>
<a name="line-58"></a>
<a name="line-59"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>dict_con</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>buildDataCon</span> <span class='hs-varid'>datacon_name</span>
<a name="line-60"></a>				   <span class='hs-conid'>False</span> 	<span class='hs-comment'>-- Not declared infix</span>
<a name="line-61"></a>				   <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>const</span> <span class='hs-conid'>NotMarkedStrict</span><span class='hs-layout'>)</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-62"></a>				   <span class='hs-keyglyph'>[</span><span class='hs-comment'>{- No fields -}</span><span class='hs-keyglyph'>]</span>
<a name="line-63"></a>				   <span class='hs-varid'>tvs</span> <span class='hs-keyglyph'>[</span><span class='hs-comment'>{- no existentials -}</span><span class='hs-keyglyph'>]</span>
<a name="line-64"></a>                                   <span class='hs-keyglyph'>[</span><span class='hs-comment'>{- No GADT equalities -}</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>[</span><span class='hs-comment'>{- No theta -}</span><span class='hs-keyglyph'>]</span>
<a name="line-65"></a>                                   <span class='hs-varid'>arg_tys</span>
<a name="line-66"></a>				   <span class='hs-layout'>(</span><span class='hs-varid'>mkTyConApp</span> <span class='hs-varid'>rec_tycon</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkTyVarTys</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-67"></a>				   <span class='hs-varid'>rec_tycon</span>
<a name="line-68"></a>
<a name="line-69"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>rhs</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>use_newtype</span>
<a name="line-70"></a>		 <span class='hs-keyword'>then</span> <span class='hs-varid'>mkNewTyConRhs</span> <span class='hs-varid'>tycon_name</span> <span class='hs-varid'>rec_tycon</span> <span class='hs-varid'>dict_con</span>
<a name="line-71"></a>		 <span class='hs-keyword'>else</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkDataTyConRhs</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>dict_con</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-72"></a>
<a name="line-73"></a>	<span class='hs-layout'>;</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>{</span>	<span class='hs-varid'>clas_kind</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkArrowKinds</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>tyVarKind</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>liftedTypeKind</span>
<a name="line-74"></a>
<a name="line-75"></a> 	      <span class='hs-layout'>;</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkClassTyCon</span> <span class='hs-varid'>tycon_name</span> <span class='hs-varid'>clas_kind</span> <span class='hs-varid'>tvs</span>
<a name="line-76"></a> 	                             <span class='hs-varid'>rhs</span> <span class='hs-varid'>rec_clas</span> <span class='hs-varid'>tc_isrec</span>
<a name="line-77"></a>		<span class='hs-comment'>-- A class can be recursive, and in the case of newtypes </span>
<a name="line-78"></a>		<span class='hs-comment'>-- this matters.  For example</span>
<a name="line-79"></a>		<span class='hs-comment'>-- 	class C a where { op :: C b =&gt; a -&gt; b -&gt; Int }</span>
<a name="line-80"></a>		<span class='hs-comment'>-- Because C has only one operation, it is represented by</span>
<a name="line-81"></a>		<span class='hs-comment'>-- a newtype, and it should be a *recursive* newtype.</span>
<a name="line-82"></a>		<span class='hs-comment'>-- [If we don't make it a recursive newtype, we'll expand the</span>
<a name="line-83"></a>		<span class='hs-comment'>-- newtype like a synonym, but that will lead to an infinite</span>
<a name="line-84"></a>		<span class='hs-comment'>-- type]</span>
<a name="line-85"></a>	      <span class='hs-layout'>;</span> <span class='hs-varid'>atTyCons</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ATyCon</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>ats</span><span class='hs-keyglyph'>]</span>
<a name="line-86"></a>
<a name="line-87"></a>	      <span class='hs-layout'>;</span> <span class='hs-varid'>result</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkClass</span> <span class='hs-varid'>class_name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>fds</span> 
<a name="line-88"></a>			         <span class='hs-varid'>sc_theta</span> <span class='hs-varid'>sc_sel_ids</span> <span class='hs-varid'>atTyCons</span>
<a name="line-89"></a>				 <span class='hs-varid'>op_items</span> <span class='hs-varid'>tycon</span>
<a name="line-90"></a>	      <span class='hs-layout'>}</span>
<a name="line-91"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>traceIf</span> <span class='hs-layout'>(</span><span class='hs-varid'>text</span> <span class='hs-str'>"buildClass"</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>tycon</span><span class='hs-layout'>)</span> 
<a name="line-92"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>result</span>
<a name="line-93"></a>	<span class='hs-layout'>}</span><span class='hs-layout'>)</span><span class='hs-layout'>}</span>
</pre>\end{code}

Note [Class newtypes and equality predicates]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
	class (a ~ F b) => C a b where
	  op :: a -> b

We cannot represent this by a newtype, even though it's not
existential, and there's only one value field, because we do
capture an equality predicate:

	data C a b where
	  MkC :: forall a b. (a ~ F b) => (a->b) -> C a b

We need to access this equality predicate when we get passes a C
dictionary.  See Trac #2238

</body>
</html>