Sophie

Sophie

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

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>types/Coercion.lhs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
%
% (c) The University of Glasgow 2006
%

\begin{code}
<pre><a name="line-1"></a><span class='hs-comment'>{-# OPTIONS -fno-warn-incomplete-patterns #-}</span>
<a name="line-2"></a><span class='hs-comment'>-- The above warning supression flag is a temporary kludge.</span>
<a name="line-3"></a><span class='hs-comment'>-- While working on this module you are encouraged to remove it and fix</span>
<a name="line-4"></a><span class='hs-comment'>-- any warnings in the module. See</span>
<a name="line-5"></a><span class='hs-comment'>--     <a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings">http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings</a></span>
<a name="line-6"></a><span class='hs-comment'>-- for details</span>
<a name="line-7"></a>
<a name="line-8"></a><span class='hs-comment'>-- | Module for type coercions, as used in System FC. See 'CoreSyn.Expr' for</span>
<a name="line-9"></a><span class='hs-comment'>-- more on System FC and how coercions fit into it.</span>
<a name="line-10"></a><span class='hs-comment'>--</span>
<a name="line-11"></a><span class='hs-comment'>-- Coercions are represented as types, and their kinds tell what types the </span>
<a name="line-12"></a><span class='hs-comment'>-- coercion works on. The coercion kind constructor is a special TyCon that must always be saturated, like so:</span>
<a name="line-13"></a><span class='hs-comment'>--</span>
<a name="line-14"></a><span class='hs-comment'>-- &gt; typeKind (symCoercion type) :: TyConApp CoercionTyCon{...} [type, type]</span>
<a name="line-15"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Coercion</span> <span class='hs-layout'>(</span>
<a name="line-16"></a>        <span class='hs-comment'>-- * Main data type</span>
<a name="line-17"></a>        <span class='hs-conid'>Coercion</span><span class='hs-layout'>,</span>
<a name="line-18"></a> 
<a name="line-19"></a>        <span class='hs-varid'>mkCoKind</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkReflCoKind</span><span class='hs-layout'>,</span> <span class='hs-varid'>splitCoercionKind_maybe</span><span class='hs-layout'>,</span> <span class='hs-varid'>splitCoercionKind</span><span class='hs-layout'>,</span>
<a name="line-20"></a>        <span class='hs-varid'>coercionKind</span><span class='hs-layout'>,</span> <span class='hs-varid'>coercionKinds</span><span class='hs-layout'>,</span> <span class='hs-varid'>coercionKindPredTy</span><span class='hs-layout'>,</span> <span class='hs-varid'>isIdentityCoercion</span><span class='hs-layout'>,</span>
<a name="line-21"></a>
<a name="line-22"></a>	<span class='hs-comment'>-- ** Equality predicates</span>
<a name="line-23"></a>	<span class='hs-varid'>isEqPred</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkEqPred</span><span class='hs-layout'>,</span> <span class='hs-varid'>getEqPredTys</span><span class='hs-layout'>,</span> <span class='hs-varid'>isEqPredTy</span><span class='hs-layout'>,</span>  
<a name="line-24"></a>
<a name="line-25"></a>	<span class='hs-comment'>-- ** Coercion transformations</span>
<a name="line-26"></a>	<span class='hs-varid'>mkCoercion</span><span class='hs-layout'>,</span>
<a name="line-27"></a>        <span class='hs-varid'>mkSymCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkTransCoercion</span><span class='hs-layout'>,</span>
<a name="line-28"></a>        <span class='hs-varid'>mkLeftCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkRightCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkRightCoercions</span><span class='hs-layout'>,</span>
<a name="line-29"></a>	<span class='hs-varid'>mkInstCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkAppCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkTyConCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkFunCoercion</span><span class='hs-layout'>,</span>
<a name="line-30"></a>        <span class='hs-varid'>mkForAllCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkInstsCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkUnsafeCoercion</span><span class='hs-layout'>,</span>
<a name="line-31"></a>        <span class='hs-varid'>mkNewTypeCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkFamInstCoercion</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkAppsCoercion</span><span class='hs-layout'>,</span>
<a name="line-32"></a>
<a name="line-33"></a>        <span class='hs-varid'>splitNewTypeRepCo_maybe</span><span class='hs-layout'>,</span> <span class='hs-varid'>instNewTyCon_maybe</span><span class='hs-layout'>,</span> <span class='hs-varid'>decomposeCo</span><span class='hs-layout'>,</span>
<a name="line-34"></a>
<a name="line-35"></a>        <span class='hs-varid'>unsafeCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>symCoercionTyCon</span><span class='hs-layout'>,</span>
<a name="line-36"></a>        <span class='hs-varid'>transCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>leftCoercionTyCon</span><span class='hs-layout'>,</span> 
<a name="line-37"></a>        <span class='hs-varid'>rightCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>instCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- needed by TysWiredIn</span>
<a name="line-38"></a>
<a name="line-39"></a>        <span class='hs-comment'>-- ** Comparison</span>
<a name="line-40"></a>        <span class='hs-varid'>coreEqCoercion</span><span class='hs-layout'>,</span>
<a name="line-41"></a>
<a name="line-42"></a>	<span class='hs-comment'>-- * CoercionI</span>
<a name="line-43"></a>	<span class='hs-conid'>CoercionI</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-44"></a>	<span class='hs-varid'>isIdentityCoI</span><span class='hs-layout'>,</span>
<a name="line-45"></a>	<span class='hs-varid'>mkSymCoI</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkTransCoI</span><span class='hs-layout'>,</span> 
<a name="line-46"></a>	<span class='hs-varid'>mkTyConAppCoI</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkAppTyCoI</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkFunTyCoI</span><span class='hs-layout'>,</span>
<a name="line-47"></a>	<span class='hs-varid'>mkForAllTyCoI</span><span class='hs-layout'>,</span>
<a name="line-48"></a>	<span class='hs-varid'>fromCoI</span><span class='hs-layout'>,</span> <span class='hs-varid'>fromACo</span><span class='hs-layout'>,</span>
<a name="line-49"></a>	<span class='hs-varid'>mkClassPPredCoI</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkIParamPredCoI</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkEqPredCoI</span>
<a name="line-50"></a>
<a name="line-51"></a>       <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> 
<a name="line-52"></a>
<a name="line-53"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-54"></a>
<a name="line-55"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TypeRep</span>
<a name="line-56"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span>
<a name="line-57"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TyCon</span>
<a name="line-58"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Class</span>
<a name="line-59"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Var</span>
<a name="line-60"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Name</span>
<a name="line-61"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>PrelNames</span>
<a name="line-62"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Util</span>
<a name="line-63"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BasicTypes</span>
<a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span>
<a name="line-65"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastString</span>
<a name="line-66"></a>
<a name="line-67"></a><a name="Coercion"></a><span class='hs-comment'>-- | A 'Coercion' represents a 'Type' something should be coerced to.</span>
<a name="line-68"></a><a name="Coercion"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>Coercion</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Type</span>
<a name="line-69"></a>
<a name="line-70"></a><a name="CoercionKind"></a><span class='hs-comment'>-- | A 'CoercionKind' is always of form @ty1 ~ ty2@ and indicates the</span>
<a name="line-71"></a><a name="CoercionKind"></a><span class='hs-comment'>-- types that a 'Coercion' will work on.</span>
<a name="line-72"></a><a name="CoercionKind"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoercionKind</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Kind</span>
<a name="line-73"></a>
<a name="line-74"></a><span class='hs-comment'>------------------------------</span>
<a name="line-75"></a>
<a name="line-76"></a><a name="decomposeCo"></a><span class='hs-comment'>-- | This breaks a 'Coercion' with 'CoercionKind' @T A B C ~ T D E F@ into</span>
<a name="line-77"></a><span class='hs-comment'>-- a list of 'Coercion's of kinds @A ~ D@, @B ~ E@ and @E ~ F@. Hence:</span>
<a name="line-78"></a><span class='hs-comment'>--</span>
<a name="line-79"></a><span class='hs-comment'>-- &gt; decomposeCo 3 c = [right (left (left c)), right (left c), right c]</span>
<a name="line-80"></a><span class='hs-definition'>decomposeCo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Arity</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Coercion</span><span class='hs-keyglyph'>]</span>
<a name="line-81"></a><span class='hs-definition'>decomposeCo</span> <span class='hs-varid'>n</span> <span class='hs-varid'>co</span>
<a name="line-82"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>n</span> <span class='hs-varid'>co</span> <span class='hs-conid'>[]</span>
<a name="line-83"></a>  <span class='hs-keyword'>where</span>
<a name="line-84"></a>    <span class='hs-varid'>go</span> <span class='hs-num'>0</span> <span class='hs-keyword'>_</span>  <span class='hs-varid'>cos</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cos</span>
<a name="line-85"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>n</span> <span class='hs-varid'>co</span> <span class='hs-varid'>cos</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkLeftCoercion</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-86"></a>			   <span class='hs-layout'>(</span><span class='hs-varid'>mkRightCoercion</span> <span class='hs-varid'>co</span> <span class='hs-conop'>:</span> <span class='hs-varid'>cos</span><span class='hs-layout'>)</span>
<a name="line-87"></a>
<a name="line-88"></a><span class='hs-comment'>------------------------------</span>
<a name="line-89"></a>
<a name="line-90"></a><span class='hs-comment'>-------------------------------------------------------</span>
<a name="line-91"></a><span class='hs-comment'>-- and some coercion kind stuff</span>
<a name="line-92"></a>
<a name="line-93"></a><a name="isEqPredTy"></a><span class='hs-comment'>-- | Tests whether a type is just a type equality predicate</span>
<a name="line-94"></a><span class='hs-definition'>isEqPredTy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-95"></a><span class='hs-definition'>isEqPredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-varid'>pred</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isEqPred</span> <span class='hs-varid'>pred</span>
<a name="line-96"></a><span class='hs-definition'>isEqPredTy</span> <span class='hs-keyword'>_</span>             <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-97"></a>
<a name="line-98"></a><a name="mkEqPred"></a><span class='hs-comment'>-- | Creates a type equality predicate</span>
<a name="line-99"></a><span class='hs-definition'>mkEqPred</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-conid'>Type</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>PredType</span>
<a name="line-100"></a><span class='hs-definition'>mkEqPred</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EqPred</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span>
<a name="line-101"></a>
<a name="line-102"></a><a name="getEqPredTys"></a><span class='hs-comment'>-- | Splits apart a type equality predicate, if the supplied 'PredType' is one.</span>
<a name="line-103"></a><span class='hs-comment'>-- Panics otherwise</span>
<a name="line-104"></a><span class='hs-definition'>getEqPredTys</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>PredType</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span><span class='hs-conid'>Type</span><span class='hs-layout'>)</span>
<a name="line-105"></a><span class='hs-definition'>getEqPredTys</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqPred</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-106"></a><span class='hs-definition'>getEqPredTys</span> <span class='hs-varid'>other</span>	      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>pprPanic</span> <span class='hs-str'>"getEqPredTys"</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-107"></a>
<a name="line-108"></a><a name="mkCoKind"></a><span class='hs-comment'>-- | Makes a 'CoercionKind' from two types: the types whose equality is proven by the relevant 'Coercion'</span>
<a name="line-109"></a><span class='hs-definition'>mkCoKind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionKind</span>
<a name="line-110"></a><span class='hs-definition'>mkCoKind</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqPred</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-111"></a>
<a name="line-112"></a><a name="mkReflCoKind"></a><span class='hs-comment'>-- | Create a reflexive 'CoercionKind' that asserts that a type can be coerced to itself</span>
<a name="line-113"></a><span class='hs-definition'>mkReflCoKind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionKind</span>
<a name="line-114"></a><span class='hs-definition'>mkReflCoKind</span> <span class='hs-varid'>ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoKind</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>ty</span>
<a name="line-115"></a>
<a name="line-116"></a><a name="splitCoercionKind"></a><span class='hs-comment'>-- | Take a 'CoercionKind' apart into the two types it relates: see also 'mkCoKind'.</span>
<a name="line-117"></a><span class='hs-comment'>-- Panics if the argument is not a valid 'CoercionKind'</span>
<a name="line-118"></a><span class='hs-definition'>splitCoercionKind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoercionKind</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span> <span class='hs-conid'>Type</span><span class='hs-layout'>)</span>
<a name="line-119"></a><span class='hs-definition'>splitCoercionKind</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>co'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>kindView</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitCoercionKind</span> <span class='hs-varid'>co'</span>
<a name="line-120"></a><span class='hs-definition'>splitCoercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqPred</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-121"></a>
<a name="line-122"></a><a name="splitCoercionKind_maybe"></a><span class='hs-comment'>-- | Take a 'CoercionKind' apart into the two types it relates, if possible. See also 'splitCoercionKind'</span>
<a name="line-123"></a><span class='hs-definition'>splitCoercionKind_maybe</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Kind</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span> <span class='hs-conid'>Type</span><span class='hs-layout'>)</span>
<a name="line-124"></a><span class='hs-definition'>splitCoercionKind_maybe</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>co'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>kindView</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitCoercionKind_maybe</span> <span class='hs-varid'>co'</span>
<a name="line-125"></a><span class='hs-definition'>splitCoercionKind_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqPred</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-126"></a><span class='hs-definition'>splitCoercionKind_maybe</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-127"></a>
<a name="line-128"></a><a name="coercionKind"></a><span class='hs-comment'>-- | If it is the case that</span>
<a name="line-129"></a><span class='hs-comment'>--</span>
<a name="line-130"></a><span class='hs-comment'>-- &gt; c :: (t1 ~ t2)</span>
<a name="line-131"></a><span class='hs-comment'>--</span>
<a name="line-132"></a><span class='hs-comment'>-- i.e. the kind of @c@ is a 'CoercionKind' relating @t1@ and @t2@, then @coercionKind c = (t1, t2)@.</span>
<a name="line-133"></a><span class='hs-comment'>-- See also 'coercionKindPredTy'</span>
<a name="line-134"></a><span class='hs-definition'>coercionKind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span> <span class='hs-conid'>Type</span><span class='hs-layout'>)</span>
<a name="line-135"></a><span class='hs-definition'>coercionKind</span> <span class='hs-varid'>ty</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>TyVarTy</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isCoVar</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitCoercionKind</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyVarKind</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-136"></a>                            <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-137"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppTy</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> 
<a name="line-138"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>t1</span><span class='hs-layout'>,</span> <span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>ty1</span>
<a name="line-139"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>s1</span><span class='hs-layout'>,</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>ty2</span> <span class='hs-keyword'>in</span>
<a name="line-140"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>mkAppTy</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>s1</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkAppTy</span> <span class='hs-varid'>t2</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span>
<a name="line-141"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-142"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ar</span><span class='hs-layout'>,</span> <span class='hs-varid'>rule</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>isCoercionTyCon_maybe</span> <span class='hs-varid'>tc</span> 
<a name="line-143"></a>    <span class='hs-comment'>-- CoercionTyCons carry their kinding rule, so we use it here</span>
<a name="line-144"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>length</span> <span class='hs-varid'>args</span> <span class='hs-varop'>&gt;=</span> <span class='hs-varid'>ar</span> <span class='hs-layout'>)</span>	<span class='hs-comment'>-- Always saturated</span>
<a name="line-145"></a>    <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span><span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rule</span> <span class='hs-layout'>(</span><span class='hs-varid'>take</span> <span class='hs-varid'>ar</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>	<span class='hs-comment'>-- Apply the rule to the right number of args</span>
<a name="line-146"></a>	<span class='hs-layout'>(</span><span class='hs-varid'>tys1</span><span class='hs-layout'>,</span> <span class='hs-varid'>tys2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKinds</span> <span class='hs-layout'>(</span><span class='hs-varid'>drop</span> <span class='hs-varid'>ar</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-147"></a>    <span class='hs-keyword'>in</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkAppTys</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>tys1</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkAppTys</span> <span class='hs-varid'>ty2</span> <span class='hs-varid'>tys2</span><span class='hs-layout'>)</span>
<a name="line-148"></a>
<a name="line-149"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-150"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>lArgs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rArgs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKinds</span> <span class='hs-varid'>args</span> <span class='hs-keyword'>in</span>
<a name="line-151"></a>    <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>lArgs</span><span class='hs-layout'>,</span> <span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>rArgs</span><span class='hs-layout'>)</span>
<a name="line-152"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>FunTy</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> 
<a name="line-153"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>t1</span><span class='hs-layout'>,</span> <span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>ty1</span>
<a name="line-154"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>s1</span><span class='hs-layout'>,</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>ty2</span> <span class='hs-keyword'>in</span>
<a name="line-155"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>mkFunTy</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>s1</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkFunTy</span> <span class='hs-varid'>t2</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span>
<a name="line-156"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>ForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> 
<a name="line-157"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>ty</span> <span class='hs-keyword'>in</span>
<a name="line-158"></a>    <span class='hs-layout'>(</span><span class='hs-conid'>ForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-conid'>ForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-159"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqPred</span> <span class='hs-varid'>c1</span> <span class='hs-varid'>c2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> 
<a name="line-160"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>k1</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKindPredTy</span> <span class='hs-varid'>c1</span>
<a name="line-161"></a>        <span class='hs-varid'>k2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKindPredTy</span> <span class='hs-varid'>c2</span> <span class='hs-keyword'>in</span>
<a name="line-162"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>k1</span><span class='hs-layout'>,</span><span class='hs-varid'>k2</span><span class='hs-layout'>)</span>
<a name="line-163"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClassP</span> <span class='hs-varid'>cl</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> 
<a name="line-164"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>lArgs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rArgs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKinds</span> <span class='hs-varid'>args</span> <span class='hs-keyword'>in</span>
<a name="line-165"></a>    <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClassP</span> <span class='hs-varid'>cl</span> <span class='hs-varid'>lArgs</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClassP</span> <span class='hs-varid'>cl</span> <span class='hs-varid'>rArgs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-166"></a><span class='hs-definition'>coercionKind</span> <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>IParam</span> <span class='hs-varid'>name</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-167"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>ty</span> <span class='hs-keyword'>in</span>
<a name="line-168"></a>    <span class='hs-layout'>(</span><span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>IParam</span> <span class='hs-varid'>name</span> <span class='hs-varid'>ty1</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>PredTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>IParam</span> <span class='hs-varid'>name</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-169"></a>
<a name="line-170"></a><a name="coercionKindPredTy"></a><span class='hs-comment'>-- | Recover the 'CoercionKind' corresponding to a particular 'Coerceion'. See also 'coercionKind'</span>
<a name="line-171"></a><span class='hs-comment'>-- and 'mkCoKind'</span>
<a name="line-172"></a><span class='hs-definition'>coercionKindPredTy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionKind</span>
<a name="line-173"></a><span class='hs-definition'>coercionKindPredTy</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>t1</span><span class='hs-layout'>,</span> <span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>c</span> <span class='hs-keyword'>in</span> <span class='hs-varid'>mkCoKind</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>t2</span>
<a name="line-174"></a>
<a name="line-175"></a><a name="coercionKinds"></a><span class='hs-comment'>-- | Apply 'coercionKind' to multiple 'Coercion's</span>
<a name="line-176"></a><span class='hs-definition'>coercionKinds</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Coercion</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</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-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-177"></a><span class='hs-definition'>coercionKinds</span> <span class='hs-varid'>tys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unzip</span> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>tys</span>
<a name="line-178"></a>
<a name="line-179"></a><a name="isIdentityCoercion"></a><span class='hs-comment'>-------------------------------------</span>
<a name="line-180"></a><span class='hs-definition'>isIdentityCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-181"></a><span class='hs-definition'>isIdentityCoercion</span> <span class='hs-varid'>co</span>  
<a name="line-182"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>co</span> <span class='hs-keyword'>of</span>
<a name="line-183"></a>       <span class='hs-layout'>(</span><span class='hs-varid'>t1</span><span class='hs-layout'>,</span><span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>t1</span> <span class='hs-varop'>`coreEqType`</span> <span class='hs-varid'>t2</span>
<a name="line-184"></a>
<a name="line-185"></a><span class='hs-comment'>-------------------------------------</span>
<a name="line-186"></a><span class='hs-comment'>-- Coercion kind and type mk's</span>
<a name="line-187"></a><span class='hs-comment'>-- (make saturated TyConApp CoercionTyCon{...} args)</span>
<a name="line-188"></a>
<a name="line-189"></a><a name="mkCoercion"></a><span class='hs-comment'>-- | Make a coercion from the specified coercion 'TyCon' and the 'Type' arguments to</span>
<a name="line-190"></a><span class='hs-comment'>-- that coercion. Try to use the @mk*Coercion@ family of functions instead of using this function</span>
<a name="line-191"></a><span class='hs-comment'>-- if possible</span>
<a name="line-192"></a><span class='hs-definition'>mkCoercion</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-conid'>Coercion</span>
<a name="line-193"></a><span class='hs-definition'>mkCoercion</span> <span class='hs-varid'>coCon</span> <span class='hs-varid'>args</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>tyConArity</span> <span class='hs-varid'>coCon</span> <span class='hs-varop'>==</span> <span class='hs-varid'>length</span> <span class='hs-varid'>args</span> <span class='hs-layout'>)</span> 
<a name="line-194"></a>                        <span class='hs-conid'>TyConApp</span> <span class='hs-varid'>coCon</span> <span class='hs-varid'>args</span>
<a name="line-195"></a>
<a name="line-196"></a><a name="mkAppCoercion"></a><span class='hs-comment'>-- | Apply a 'Coercion' to another 'Coercion', which is presumably a</span>
<a name="line-197"></a><span class='hs-comment'>-- 'Coercion' constructor of some kind</span>
<a name="line-198"></a><span class='hs-definition'>mkAppCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-199"></a><span class='hs-definition'>mkAppCoercion</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkAppTy</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span>
<a name="line-200"></a>
<a name="line-201"></a><a name="mkAppsCoercion"></a><span class='hs-comment'>-- | Applies multiple 'Coercion's to another 'Coercion', from left to right.</span>
<a name="line-202"></a><span class='hs-comment'>-- See also 'mkAppCoercion'</span>
<a name="line-203"></a><span class='hs-definition'>mkAppsCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Coercion</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-204"></a><span class='hs-definition'>mkAppsCoercion</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>tys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldl</span> <span class='hs-varid'>mkAppTy</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>tys</span>
<a name="line-205"></a>
<a name="line-206"></a><a name="mkTyConCoercion"></a><span class='hs-comment'>-- | Apply a type constructor to a list of coercions.</span>
<a name="line-207"></a><span class='hs-definition'>mkTyConCoercion</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'>Coercion</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-208"></a><span class='hs-definition'>mkTyConCoercion</span> <span class='hs-varid'>con</span> <span class='hs-varid'>cos</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkTyConApp</span> <span class='hs-varid'>con</span> <span class='hs-varid'>cos</span>
<a name="line-209"></a>
<a name="line-210"></a><a name="mkFunCoercion"></a><span class='hs-comment'>-- | Make a function 'Coercion' between two other 'Coercion's</span>
<a name="line-211"></a><span class='hs-definition'>mkFunCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-212"></a><span class='hs-definition'>mkFunCoercion</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkFunTy</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span>
<a name="line-213"></a>
<a name="line-214"></a><a name="mkForAllCoercion"></a><span class='hs-comment'>-- | Make a 'Coercion' which binds a variable within an inner 'Coercion'</span>
<a name="line-215"></a><span class='hs-definition'>mkForAllCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-216"></a><span class='hs-comment'>-- note that a TyVar should be used here, not a CoVar (nor a TcTyVar)</span>
<a name="line-217"></a><span class='hs-definition'>mkForAllCoercion</span> <span class='hs-varid'>tv</span>  <span class='hs-varid'>co</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span> <span class='hs-layout'>(</span> <span class='hs-varid'>isTyVar</span> <span class='hs-varid'>tv</span> <span class='hs-layout'>)</span> <span class='hs-varid'>mkForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>co</span>
<a name="line-218"></a>
<a name="line-219"></a>
<a name="line-220"></a><span class='hs-comment'>-------------------------------</span>
<a name="line-221"></a>
<a name="line-222"></a><a name="mkSymCoercion"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-223"></a><span class='hs-comment'>-- ^ Create a symmetric version of the given 'Coercion' that asserts equality</span>
<a name="line-224"></a><span class='hs-comment'>-- between the same types but in the other "direction", so a kind of @t1 ~ t2@ </span>
<a name="line-225"></a><span class='hs-comment'>-- becomes the kind @t2 ~ t1@.</span>
<a name="line-226"></a><span class='hs-comment'>--</span>
<a name="line-227"></a><span class='hs-comment'>-- This function attempts to simplify the generated 'Coercion' by removing </span>
<a name="line-228"></a><span class='hs-comment'>-- redundant applications of @sym@. This is done by pushing this new @sym@ </span>
<a name="line-229"></a><span class='hs-comment'>-- down into the 'Coercion' and exploiting the fact that @sym (sym co) = co@.</span>
<a name="line-230"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-varid'>co</span>      
<a name="line-231"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>co'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>coreView</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co'</span>
<a name="line-232"></a>
<a name="line-233"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>ForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-234"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppTy</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span> 	<span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppTy</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span>
<a name="line-235"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>FunTy</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span> 	<span class='hs-keyglyph'>=</span> <span class='hs-conid'>FunTy</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span>
<a name="line-236"></a>
<a name="line-237"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>cos</span><span class='hs-layout'>)</span> 
<a name="line-238"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isCoercionTyCon</span> <span class='hs-varid'>tc</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkTyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>cos</span><span class='hs-layout'>)</span>
<a name="line-239"></a>
<a name="line-240"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> 
<a name="line-241"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tc</span> <span class='hs-varop'>`hasKey`</span> <span class='hs-varid'>symCoercionTyConKey</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>co</span>    <span class='hs-comment'>-- sym (sym co) --&gt; co</span>
<a name="line-242"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tc</span> <span class='hs-varop'>`hasKey`</span> <span class='hs-varid'>leftCoercionTyConKey</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkLeftCoercion</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-243"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tc</span> <span class='hs-varop'>`hasKey`</span> <span class='hs-varid'>rightCoercionTyConKey</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkRightCoercion</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-244"></a>
<a name="line-245"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co1</span><span class='hs-layout'>,</span><span class='hs-varid'>co2</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> 
<a name="line-246"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tc</span> <span class='hs-varop'>`hasKey`</span> <span class='hs-varid'>transCoercionTyConKey</span>
<a name="line-247"></a>     <span class='hs-comment'>-- sym (co1 `trans` co2) --&gt; (sym co2) `trans (sym co2)</span>
<a name="line-248"></a>     <span class='hs-comment'>-- Note reversal of arguments!</span>
<a name="line-249"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkTransCoercion</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co1</span><span class='hs-layout'>)</span>
<a name="line-250"></a>
<a name="line-251"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tc</span> <span class='hs-varop'>`hasKey`</span> <span class='hs-varid'>instCoercionTyConKey</span>
<a name="line-252"></a>     <span class='hs-comment'>-- sym (co @ ty) --&gt; (sym co) @ ty</span>
<a name="line-253"></a>     <span class='hs-comment'>-- Note: sym is not applied to 'ty'</span>
<a name="line-254"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkInstCoercion</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSymCoercion</span> <span class='hs-varid'>co1</span><span class='hs-layout'>)</span> <span class='hs-varid'>co2</span>
<a name="line-255"></a>
<a name="line-256"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>cos</span><span class='hs-layout'>)</span> 	<span class='hs-comment'>-- Other coercion tycons, such as those</span>
<a name="line-257"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>symCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>cos</span><span class='hs-keyglyph'>]</span>  <span class='hs-comment'>-- arising from newtypes</span>
<a name="line-258"></a>
<a name="line-259"></a><span class='hs-definition'>mkSymCoercion</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyVarTy</span> <span class='hs-varid'>tv</span><span class='hs-layout'>)</span> 
<a name="line-260"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isCoVar</span> <span class='hs-varid'>tv</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>symCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVarTy</span> <span class='hs-varid'>tv</span><span class='hs-keyglyph'>]</span>
<a name="line-261"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>TyVarTy</span> <span class='hs-varid'>tv</span>	<span class='hs-comment'>-- Reflexive</span>
<a name="line-262"></a>
<a name="line-263"></a><span class='hs-comment'>-------------------------------</span>
<a name="line-264"></a><span class='hs-comment'>-- ToDo: we should be cleverer about transitivity</span>
<a name="line-265"></a>
<a name="line-266"></a><a name="mkTransCoercion"></a><span class='hs-definition'>mkTransCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-267"></a><span class='hs-comment'>-- ^ Create a new 'Coercion' by exploiting transitivity on the two given 'Coercion's.</span>
<a name="line-268"></a><span class='hs-comment'>-- </span>
<a name="line-269"></a><span class='hs-comment'>-- This function attempts to simplify the generated 'Coercion' by exploiting the fact that</span>
<a name="line-270"></a><span class='hs-comment'>-- @sym g `trans` g = id@.</span>
<a name="line-271"></a><span class='hs-definition'>mkTransCoercion</span> <span class='hs-varid'>g1</span> <span class='hs-varid'>g2</span>	<span class='hs-comment'>-- sym g `trans` g = id</span>
<a name="line-272"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>t1</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'>coercionKind</span> <span class='hs-varid'>g1</span>
<a name="line-273"></a>  <span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>g2</span>
<a name="line-274"></a>  <span class='hs-layout'>,</span> <span class='hs-varid'>t1</span> <span class='hs-varop'>`coreEqType`</span> <span class='hs-varid'>t2</span> 
<a name="line-275"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>t1</span>	
<a name="line-276"></a>
<a name="line-277"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-278"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>transCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>g1</span><span class='hs-layout'>,</span> <span class='hs-varid'>g2</span><span class='hs-keyglyph'>]</span>
<a name="line-279"></a>
<a name="line-280"></a>
<a name="line-281"></a><span class='hs-comment'>-------------------------------</span>
<a name="line-282"></a><span class='hs-comment'>-- Smart constructors for left and right</span>
<a name="line-283"></a>
<a name="line-284"></a><a name="mkLeftCoercion"></a><span class='hs-definition'>mkLeftCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-285"></a><span class='hs-comment'>-- ^ From an application 'Coercion' build a 'Coercion' that asserts the equality of </span>
<a name="line-286"></a><span class='hs-comment'>-- the "functions" on either side of the type equality. So if @c@ has kind @f x ~ g y@ then:</span>
<a name="line-287"></a><span class='hs-comment'>--</span>
<a name="line-288"></a><span class='hs-comment'>-- &gt; mkLeftCoercion c :: f ~ g</span>
<a name="line-289"></a><span class='hs-definition'>mkLeftCoercion</span> <span class='hs-varid'>co</span> 
<a name="line-290"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>co'</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'>splitAppCoercion_maybe</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>co'</span>
<a name="line-291"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>leftCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-keyglyph'>]</span>
<a name="line-292"></a>
<a name="line-293"></a><a name="mkRightCoercion"></a><span class='hs-definition'>mkRightCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-294"></a><span class='hs-comment'>-- ^ From an application 'Coercion' build a 'Coercion' that asserts the equality of </span>
<a name="line-295"></a><span class='hs-comment'>-- the "arguments" on either side of the type equality. So if @c@ has kind @f x ~ g y@ then:</span>
<a name="line-296"></a><span class='hs-comment'>--</span>
<a name="line-297"></a><span class='hs-comment'>-- &gt; mkLeftCoercion c :: x ~ y</span>
<a name="line-298"></a><span class='hs-definition'>mkRightCoercion</span>  <span class='hs-varid'>co</span>      
<a name="line-299"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>splitAppCoercion_maybe</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>co2</span>
<a name="line-300"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>rightCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-keyglyph'>]</span>
<a name="line-301"></a>
<a name="line-302"></a><a name="mkRightCoercions"></a><span class='hs-definition'>mkRightCoercions</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Coercion</span><span class='hs-keyglyph'>]</span>
<a name="line-303"></a><span class='hs-comment'>-- ^ As 'mkRightCoercion', but finds the 'Coercion's available on the right side of @n@</span>
<a name="line-304"></a><span class='hs-comment'>-- nested application 'Coercion's, manufacturing new left or right cooercions as necessary</span>
<a name="line-305"></a><span class='hs-comment'>-- if suffficiently many are not directly available.</span>
<a name="line-306"></a><span class='hs-definition'>mkRightCoercions</span> <span class='hs-varid'>n</span> <span class='hs-varid'>co</span>
<a name="line-307"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>n</span> <span class='hs-varid'>co</span> <span class='hs-conid'>[]</span>
<a name="line-308"></a>  <span class='hs-keyword'>where</span>
<a name="line-309"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>n</span> <span class='hs-varid'>co</span> <span class='hs-varid'>acc</span> 
<a name="line-310"></a>       <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span>
<a name="line-311"></a>       <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>splitAppCoercion_maybe</span> <span class='hs-varid'>co</span> <span class='hs-keyword'>of</span>
<a name="line-312"></a>          <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>co1</span><span class='hs-layout'>,</span><span class='hs-varid'>co2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-varid'>co1</span> <span class='hs-layout'>(</span><span class='hs-varid'>co2</span><span class='hs-conop'>:</span><span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
<a name="line-313"></a>          <span class='hs-conid'>Nothing</span>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>leftCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>rightCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-keyglyph'>]</span><span class='hs-conop'>:</span><span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
<a name="line-314"></a>       <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-315"></a>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>acc</span>
<a name="line-316"></a>
<a name="line-317"></a>
<a name="line-318"></a><a name="mkInstCoercion"></a><span class='hs-definition'>mkInstCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-319"></a><span class='hs-comment'>-- ^ Instantiates a 'Coercion' with a 'Type' argument. If possible, it immediately performs</span>
<a name="line-320"></a><span class='hs-comment'>-- the resulting beta-reduction, otherwise it creates a suspended instantiation.</span>
<a name="line-321"></a><span class='hs-definition'>mkInstCoercion</span> <span class='hs-varid'>co</span> <span class='hs-varid'>ty</span>
<a name="line-322"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>tv</span><span class='hs-layout'>,</span><span class='hs-varid'>co'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>splitForAllTy_maybe</span> <span class='hs-varid'>co</span>
<a name="line-323"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substTyWith</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>tv</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-varid'>co'</span>	<span class='hs-comment'>-- (forall a.co) @ ty  --&gt;  co[ty/a]</span>
<a name="line-324"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-325"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>instCoercionTyCon</span>  <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty</span><span class='hs-keyglyph'>]</span>
<a name="line-326"></a>
<a name="line-327"></a><a name="mkInstsCoercion"></a><span class='hs-definition'>mkInstsCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</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-conid'>Coercion</span>
<a name="line-328"></a><span class='hs-comment'>-- ^ As 'mkInstCoercion', but instantiates the coercion with a number of type arguments, left-to-right</span>
<a name="line-329"></a><span class='hs-definition'>mkInstsCoercion</span> <span class='hs-varid'>co</span> <span class='hs-varid'>tys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldl</span> <span class='hs-varid'>mkInstCoercion</span> <span class='hs-varid'>co</span> <span class='hs-varid'>tys</span>
<a name="line-330"></a>
<a name="line-331"></a><span class='hs-comment'>{-
<a name="line-332"></a>splitSymCoercion_maybe :: Coercion -&gt; Maybe Coercion
<a name="line-333"></a>splitSymCoercion_maybe (TyConApp tc [co]) = 
<a name="line-334"></a>  if tc `hasKey` symCoercionTyConKey
<a name="line-335"></a>  then Just co
<a name="line-336"></a>  else Nothing
<a name="line-337"></a>splitSymCoercion_maybe co = Nothing
<a name="line-338"></a>-}</span>
<a name="line-339"></a>
<a name="line-340"></a><a name="splitAppCoercion_maybe"></a><span class='hs-definition'>splitAppCoercion_maybe</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Coercion</span><span class='hs-layout'>,</span> <span class='hs-conid'>Coercion</span><span class='hs-layout'>)</span>
<a name="line-341"></a><span class='hs-comment'>-- ^ Splits a coercion application, being careful *not* to split @left c@ etc.</span>
<a name="line-342"></a><span class='hs-comment'>-- This is because those are really syntactic constructs, not applications</span>
<a name="line-343"></a><span class='hs-definition'>splitAppCoercion_maybe</span> <span class='hs-varid'>co</span>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>co'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>coreView</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitAppCoercion_maybe</span> <span class='hs-varid'>co'</span>
<a name="line-344"></a><span class='hs-definition'>splitAppCoercion_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>FunTy</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>funTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>ty1</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-345"></a><span class='hs-definition'>splitAppCoercion_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppTy</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-346"></a><span class='hs-definition'>splitAppCoercion_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>tys</span><span class='hs-layout'>)</span> 
<a name="line-347"></a>   <span class='hs-keyglyph'>|</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isCoercionTyCon</span> <span class='hs-varid'>tc</span><span class='hs-layout'>)</span>
<a name="line-348"></a>   <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>snocView</span> <span class='hs-varid'>tys</span> <span class='hs-keyword'>of</span>
<a name="line-349"></a>       <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>tys'</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>tys'</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty'</span><span class='hs-layout'>)</span>
<a name="line-350"></a>       <span class='hs-conid'>Nothing</span>          <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nothing</span>
<a name="line-351"></a><span class='hs-definition'>splitAppCoercion_maybe</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-352"></a>
<a name="line-353"></a><span class='hs-comment'>{-
<a name="line-354"></a>splitTransCoercion_maybe :: Coercion -&gt; Maybe (Coercion, Coercion)
<a name="line-355"></a>splitTransCoercion_maybe (TyConApp tc [ty1, ty2]) 
<a name="line-356"></a> = if tc `hasKey` transCoercionTyConKey then
<a name="line-357"></a>       Just (ty1, ty2)
<a name="line-358"></a>   else
<a name="line-359"></a>       Nothing
<a name="line-360"></a>splitTransCoercion_maybe other = Nothing
<a name="line-361"></a>
<a name="line-362"></a>splitInstCoercion_maybe :: Coercion -&gt; Maybe (Coercion, Type)
<a name="line-363"></a>splitInstCoercion_maybe (TyConApp tc [ty1, ty2])
<a name="line-364"></a> = if tc `hasKey` instCoercionTyConKey then
<a name="line-365"></a>       Just (ty1, ty2)
<a name="line-366"></a>    else
<a name="line-367"></a>       Nothing
<a name="line-368"></a>splitInstCoercion_maybe other = Nothing
<a name="line-369"></a>
<a name="line-370"></a>splitLeftCoercion_maybe :: Coercion -&gt; Maybe Coercion
<a name="line-371"></a>splitLeftCoercion_maybe (TyConApp tc [co])
<a name="line-372"></a> = if tc `hasKey` leftCoercionTyConKey then
<a name="line-373"></a>       Just co
<a name="line-374"></a>   else
<a name="line-375"></a>       Nothing
<a name="line-376"></a>splitLeftCoercion_maybe other = Nothing
<a name="line-377"></a>
<a name="line-378"></a>splitRightCoercion_maybe :: Coercion -&gt; Maybe Coercion
<a name="line-379"></a>splitRightCoercion_maybe (TyConApp tc [co])
<a name="line-380"></a> = if tc `hasKey` rightCoercionTyConKey then
<a name="line-381"></a>       Just co
<a name="line-382"></a>   else
<a name="line-383"></a>       Nothing
<a name="line-384"></a>splitRightCoercion_maybe other = Nothing
<a name="line-385"></a>-}</span>
<a name="line-386"></a>
<a name="line-387"></a><a name="mkUnsafeCoercion"></a><span class='hs-comment'>-- | Manufacture a coercion from this air. Needless to say, this is not usually safe,</span>
<a name="line-388"></a><span class='hs-comment'>-- but it is used when we know we are dealing with bottom, which is one case in which </span>
<a name="line-389"></a><span class='hs-comment'>-- it is safe.  This is also used implement the @unsafeCoerce#@ primitive.</span>
<a name="line-390"></a><span class='hs-definition'>mkUnsafeCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-391"></a><span class='hs-definition'>mkUnsafeCoercion</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>ty2</span> 
<a name="line-392"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>unsafeCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-keyglyph'>]</span>
<a name="line-393"></a>
<a name="line-394"></a>
<a name="line-395"></a><span class='hs-comment'>-- See note [Newtype coercions] in TyCon</span>
<a name="line-396"></a>
<a name="line-397"></a><a name="mkNewTypeCoercion"></a><span class='hs-comment'>-- | Create a coercion suitable for the given 'TyCon'. The 'Name' should be that of a</span>
<a name="line-398"></a><span class='hs-comment'>-- new coercion 'TyCon', the 'TyVar's the arguments expected by the @newtype@ and the</span>
<a name="line-399"></a><span class='hs-comment'>-- type the appropriate right hand side of the @newtype@, with the free variables</span>
<a name="line-400"></a><span class='hs-comment'>-- a subset of those 'TyVar's.</span>
<a name="line-401"></a><span class='hs-definition'>mkNewTypeCoercion</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-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span>
<a name="line-402"></a><span class='hs-definition'>mkNewTypeCoercion</span> <span class='hs-varid'>name</span> <span class='hs-varid'>tycon</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>rhs_ty</span>
<a name="line-403"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>name</span> <span class='hs-varid'>co_con_arity</span> <span class='hs-varid'>rule</span>
<a name="line-404"></a>  <span class='hs-keyword'>where</span>
<a name="line-405"></a>    <span class='hs-varid'>co_con_arity</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>tvs</span>
<a name="line-406"></a>
<a name="line-407"></a>    <span class='hs-varid'>rule</span> <span class='hs-varid'>args</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>co_con_arity</span> <span class='hs-varop'>==</span> <span class='hs-varid'>length</span> <span class='hs-varid'>args</span> <span class='hs-layout'>)</span>
<a name="line-408"></a>		<span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tycon</span> <span class='hs-varid'>args</span><span class='hs-layout'>,</span> <span class='hs-varid'>substTyWith</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>args</span> <span class='hs-varid'>rhs_ty</span><span class='hs-layout'>)</span>
<a name="line-409"></a>
<a name="line-410"></a><a name="mkFamInstCoercion"></a><span class='hs-comment'>-- | Create a coercion identifying a @data@, @newtype@ or @type@ representation type</span>
<a name="line-411"></a><span class='hs-comment'>-- and its family instance.  It has the form @Co tvs :: F ts ~ R tvs@, where @Co@ is </span>
<a name="line-412"></a><span class='hs-comment'>-- the coercion tycon built here, @F@ the family tycon and @R@ the (derived)</span>
<a name="line-413"></a><span class='hs-comment'>-- representation tycon.</span>
<a name="line-414"></a><span class='hs-definition'>mkFamInstCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span>	<span class='hs-comment'>-- ^ Unique name for the coercion tycon</span>
<a name="line-415"></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-comment'>-- ^ Type parameters of the coercion (@tvs@)</span>
<a name="line-416"></a>		  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span>	<span class='hs-comment'>-- ^ Family tycon (@F@)</span>
<a name="line-417"></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-comment'>-- ^ Type instance (@ts@)</span>
<a name="line-418"></a>		  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span>	<span class='hs-comment'>-- ^ Representation tycon (@R@)</span>
<a name="line-419"></a>		  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span>	<span class='hs-comment'>-- ^ Coercion tycon (@Co@)</span>
<a name="line-420"></a><span class='hs-definition'>mkFamInstCoercion</span> <span class='hs-varid'>name</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>family</span> <span class='hs-varid'>instTys</span> <span class='hs-varid'>rep_tycon</span>
<a name="line-421"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>name</span> <span class='hs-varid'>coArity</span> <span class='hs-varid'>rule</span>
<a name="line-422"></a>  <span class='hs-keyword'>where</span>
<a name="line-423"></a>    <span class='hs-varid'>coArity</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>tvs</span>
<a name="line-424"></a>    <span class='hs-varid'>rule</span> <span class='hs-varid'>args</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTyWith</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>args</span> <span class='hs-varop'>$</span>		     <span class='hs-comment'>-- with sigma = [tys/tvs],</span>
<a name="line-425"></a>		   <span class='hs-conid'>TyConApp</span> <span class='hs-varid'>family</span> <span class='hs-varid'>instTys</span><span class='hs-layout'>,</span>	     <span class='hs-comment'>--       sigma (F ts)</span>
<a name="line-426"></a>		 <span class='hs-conid'>TyConApp</span> <span class='hs-varid'>rep_tycon</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>	     <span class='hs-comment'>--   ~ R tys</span>
<a name="line-427"></a>
<a name="line-428"></a><span class='hs-comment'>--------------------------------------</span>
<a name="line-429"></a><span class='hs-comment'>-- Coercion Type Constructors...</span>
<a name="line-430"></a>
<a name="line-431"></a><span class='hs-comment'>-- Example.  The coercion ((sym c) (sym d) (sym e))</span>
<a name="line-432"></a><span class='hs-comment'>-- will be represented by (TyConApp sym [c, sym d, sym e])</span>
<a name="line-433"></a><span class='hs-comment'>-- If sym c :: p1=q1</span>
<a name="line-434"></a><span class='hs-comment'>--    sym d :: p2=q2</span>
<a name="line-435"></a><span class='hs-comment'>--    sym e :: p3=q3</span>
<a name="line-436"></a><span class='hs-comment'>-- then ((sym c) (sym d) (sym e)) :: (p1 p2 p3)=(q1 q2 q3)</span>
<a name="line-437"></a>
<a name="line-438"></a><a name="symCoercionTyCon"></a><span class='hs-comment'>-- | Coercion type constructors: avoid using these directly and instead use the @mk*Coercion@ and @split*Coercion@ family</span>
<a name="line-439"></a><span class='hs-comment'>-- of functions if possible.</span>
<a name="line-440"></a><span class='hs-definition'>symCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>transCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>leftCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>rightCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>instCoercionTyCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>unsafeCoercionTyCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TyCon</span>
<a name="line-441"></a><span class='hs-comment'>-- Each coercion TyCon is built with the special CoercionTyCon record and</span>
<a name="line-442"></a><span class='hs-comment'>-- carries its own kinding rule.  Such CoercionTyCons must be fully applied</span>
<a name="line-443"></a><span class='hs-comment'>-- by any TyConApp in which they are applied, however they may also be over</span>
<a name="line-444"></a><span class='hs-comment'>-- applied (see example above) and the kinding function must deal with this.</span>
<a name="line-445"></a><span class='hs-definition'>symCoercionTyCon</span> <span class='hs-keyglyph'>=</span> 
<a name="line-446"></a>  <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>symCoercionTyConName</span> <span class='hs-num'>1</span> <span class='hs-varid'>flipCoercionKindOf</span>
<a name="line-447"></a>  <span class='hs-keyword'>where</span>
<a name="line-448"></a>    <span class='hs-varid'>flipCoercionKindOf</span> <span class='hs-layout'>(</span><span class='hs-varid'>co</span><span class='hs-conop'>:</span><span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>null</span> <span class='hs-varid'>rest</span> <span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty2</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty1</span><span class='hs-layout'>)</span>
<a name="line-449"></a>	<span class='hs-keyword'>where</span>
<a name="line-450"></a>	  <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>co</span>
<a name="line-451"></a>
<a name="line-452"></a><a name="transCoercionTyCon"></a><span class='hs-definition'>transCoercionTyCon</span> <span class='hs-keyglyph'>=</span> 
<a name="line-453"></a>  <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>transCoercionTyConName</span> <span class='hs-num'>2</span> <span class='hs-varid'>composeCoercionKindsOf</span>
<a name="line-454"></a>  <span class='hs-keyword'>where</span>
<a name="line-455"></a>    <span class='hs-varid'>composeCoercionKindsOf</span> <span class='hs-layout'>(</span><span class='hs-varid'>co1</span><span class='hs-conop'>:</span><span class='hs-varid'>co2</span><span class='hs-conop'>:</span><span class='hs-varid'>rest</span><span class='hs-layout'>)</span>
<a name="line-456"></a>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>null</span> <span class='hs-varid'>rest</span> <span class='hs-layout'>)</span>
<a name="line-457"></a>        <span class='hs-conid'>WARN</span><span class='hs-layout'>(</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>r1</span> <span class='hs-varop'>`coreEqType`</span> <span class='hs-varid'>a2</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> 
<a name="line-458"></a>              <span class='hs-varid'>text</span> <span class='hs-str'>"Strange! Type mismatch in trans coercion, probably a bug"</span>
<a name="line-459"></a>              <span class='hs-varop'>$$</span>
<a name="line-460"></a>              <span class='hs-varid'>ppr</span> <span class='hs-varid'>r1</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>text</span> <span class='hs-str'>"=/="</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>a2</span><span class='hs-layout'>)</span>
<a name="line-461"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>a1</span><span class='hs-layout'>,</span> <span class='hs-varid'>r2</span><span class='hs-layout'>)</span>
<a name="line-462"></a>      <span class='hs-keyword'>where</span>
<a name="line-463"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>a1</span><span class='hs-layout'>,</span> <span class='hs-varid'>r1</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>co1</span>
<a name="line-464"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>a2</span><span class='hs-layout'>,</span> <span class='hs-varid'>r2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>co2</span> 
<a name="line-465"></a>
<a name="line-466"></a><a name="leftCoercionTyCon"></a><span class='hs-definition'>leftCoercionTyCon</span> <span class='hs-keyglyph'>=</span>
<a name="line-467"></a>  <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>leftCoercionTyConName</span> <span class='hs-num'>1</span> <span class='hs-varid'>leftProjectCoercionKindOf</span>
<a name="line-468"></a>  <span class='hs-keyword'>where</span>
<a name="line-469"></a>    <span class='hs-varid'>leftProjectCoercionKindOf</span> <span class='hs-layout'>(</span><span class='hs-varid'>co</span><span class='hs-conop'>:</span><span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>null</span> <span class='hs-varid'>rest</span> <span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-470"></a>      <span class='hs-keyword'>where</span>
<a name="line-471"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span><span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fst</span> <span class='hs-layout'>(</span><span class='hs-varid'>splitCoercionKindOf</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-472"></a>
<a name="line-473"></a><a name="rightCoercionTyCon"></a><span class='hs-definition'>rightCoercionTyCon</span> <span class='hs-keyglyph'>=</span>
<a name="line-474"></a>  <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>rightCoercionTyConName</span> <span class='hs-num'>1</span> <span class='hs-varid'>rightProjectCoercionKindOf</span>
<a name="line-475"></a>  <span class='hs-keyword'>where</span>
<a name="line-476"></a>    <span class='hs-varid'>rightProjectCoercionKindOf</span> <span class='hs-layout'>(</span><span class='hs-varid'>co</span><span class='hs-conop'>:</span><span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>null</span> <span class='hs-varid'>rest</span> <span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-477"></a>      <span class='hs-keyword'>where</span>
<a name="line-478"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span><span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>snd</span> <span class='hs-layout'>(</span><span class='hs-varid'>splitCoercionKindOf</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-479"></a>
<a name="line-480"></a><a name="splitCoercionKindOf"></a><span class='hs-definition'>splitCoercionKindOf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span><span class='hs-conid'>Type</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span><span class='hs-conid'>Type</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-481"></a><span class='hs-comment'>-- Helper for left and right.  Finds coercion kind of its input and</span>
<a name="line-482"></a><span class='hs-comment'>-- returns the left and right projections of the coercion...</span>
<a name="line-483"></a><span class='hs-comment'>--</span>
<a name="line-484"></a><span class='hs-comment'>-- if c :: t1 s1 ~ t2 s2 then splitCoercionKindOf c = ((t1, t2), (s1, s2))</span>
<a name="line-485"></a><span class='hs-definition'>splitCoercionKindOf</span> <span class='hs-varid'>co</span>
<a name="line-486"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>splitCoercionKind_maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>coercionKindPredTy</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-487"></a>  <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty_fun1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty_arg1</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>splitAppTy_maybe</span> <span class='hs-varid'>ty1</span>
<a name="line-488"></a>  <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty_fun2</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty_arg2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>splitAppTy_maybe</span> <span class='hs-varid'>ty2</span>
<a name="line-489"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>ty_fun1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty_fun2</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span><span class='hs-layout'>(</span><span class='hs-varid'>ty_arg1</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty_arg2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-490"></a><span class='hs-definition'>splitCoercionKindOf</span> <span class='hs-varid'>co</span> 
<a name="line-491"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>pprPanic</span> <span class='hs-str'>"Coercion.splitCoercionKindOf"</span> 
<a name="line-492"></a>             <span class='hs-layout'>(</span><span class='hs-varid'>ppr</span> <span class='hs-varid'>co</span> <span class='hs-varop'>$$</span> <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-varid'>coercionKindPredTy</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-493"></a>
<a name="line-494"></a><a name="instCoercionTyCon"></a><span class='hs-definition'>instCoercionTyCon</span> 
<a name="line-495"></a>  <span class='hs-keyglyph'>=</span>  <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>instCoercionTyConName</span> <span class='hs-num'>2</span> <span class='hs-varid'>instCoercionKind</span>
<a name="line-496"></a>  <span class='hs-keyword'>where</span>
<a name="line-497"></a>    <span class='hs-varid'>instantiateCo</span> <span class='hs-varid'>t</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span>
<a name="line-498"></a>      <span class='hs-keyword'>let</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>tv</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitForAllTy_maybe</span> <span class='hs-varid'>t</span> <span class='hs-keyword'>in</span>
<a name="line-499"></a>      <span class='hs-varid'>substTyWith</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>tv</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>s</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>ty</span>
<a name="line-500"></a>
<a name="line-501"></a>    <span class='hs-varid'>instCoercionKind</span> <span class='hs-layout'>(</span><span class='hs-varid'>co1</span><span class='hs-conop'>:</span><span class='hs-varid'>ty</span><span class='hs-conop'>:</span><span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>null</span> <span class='hs-varid'>rest</span> <span class='hs-layout'>)</span>
<a name="line-502"></a>				     <span class='hs-layout'>(</span><span class='hs-varid'>instantiateCo</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span> <span class='hs-varid'>instantiateCo</span> <span class='hs-varid'>t2</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-503"></a>      <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>t1</span><span class='hs-layout'>,</span> <span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coercionKind</span> <span class='hs-varid'>co1</span>
<a name="line-504"></a>
<a name="line-505"></a><a name="unsafeCoercionTyCon"></a><span class='hs-definition'>unsafeCoercionTyCon</span> 
<a name="line-506"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoercionTyCon</span> <span class='hs-varid'>unsafeCoercionTyConName</span> <span class='hs-num'>2</span> <span class='hs-varid'>unsafeCoercionKind</span>
<a name="line-507"></a>  <span class='hs-keyword'>where</span>
<a name="line-508"></a>   <span class='hs-varid'>unsafeCoercionKind</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-conop'>:</span><span class='hs-varid'>ty2</span><span class='hs-conop'>:</span><span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>null</span> <span class='hs-varid'>rest</span> <span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty1</span><span class='hs-layout'>,</span><span class='hs-varid'>ty2</span><span class='hs-layout'>)</span> 
<a name="line-509"></a>        
<a name="line-510"></a><span class='hs-comment'>--------------------------------------</span>
<a name="line-511"></a><span class='hs-comment'>-- ...and their names</span>
<a name="line-512"></a>
<a name="line-513"></a><a name="mkCoConName"></a><span class='hs-definition'>mkCoConName</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastString</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Unique</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Name</span>
<a name="line-514"></a><span class='hs-definition'>mkCoConName</span> <span class='hs-varid'>occ</span> <span class='hs-varid'>key</span> <span class='hs-varid'>coCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkWiredInName</span> <span class='hs-varid'>gHC_PRIM</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkTcOccFS</span> <span class='hs-varid'>occ</span><span class='hs-layout'>)</span>
<a name="line-515"></a>                            <span class='hs-varid'>key</span> <span class='hs-layout'>(</span><span class='hs-conid'>ATyCon</span> <span class='hs-varid'>coCon</span><span class='hs-layout'>)</span> <span class='hs-conid'>BuiltInSyntax</span>
<a name="line-516"></a>
<a name="line-517"></a><a name="transCoercionTyConName"></a><span class='hs-definition'>transCoercionTyConName</span><span class='hs-layout'>,</span> <span class='hs-varid'>symCoercionTyConName</span><span class='hs-layout'>,</span> <span class='hs-varid'>leftCoercionTyConName</span><span class='hs-layout'>,</span> <span class='hs-varid'>rightCoercionTyConName</span><span class='hs-layout'>,</span> <span class='hs-varid'>instCoercionTyConName</span><span class='hs-layout'>,</span> <span class='hs-varid'>unsafeCoercionTyConName</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span>
<a name="line-518"></a>
<a name="line-519"></a><span class='hs-definition'>transCoercionTyConName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoConName</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsLit</span> <span class='hs-str'>"trans"</span><span class='hs-layout'>)</span> <span class='hs-varid'>transCoercionTyConKey</span> <span class='hs-varid'>transCoercionTyCon</span>
<a name="line-520"></a><a name="symCoercionTyConName"></a><span class='hs-definition'>symCoercionTyConName</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoConName</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsLit</span> <span class='hs-str'>"sym"</span><span class='hs-layout'>)</span> <span class='hs-varid'>symCoercionTyConKey</span> <span class='hs-varid'>symCoercionTyCon</span>
<a name="line-521"></a><a name="leftCoercionTyConName"></a><span class='hs-definition'>leftCoercionTyConName</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoConName</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsLit</span> <span class='hs-str'>"left"</span><span class='hs-layout'>)</span> <span class='hs-varid'>leftCoercionTyConKey</span> <span class='hs-varid'>leftCoercionTyCon</span>
<a name="line-522"></a><a name="rightCoercionTyConName"></a><span class='hs-definition'>rightCoercionTyConName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoConName</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsLit</span> <span class='hs-str'>"right"</span><span class='hs-layout'>)</span> <span class='hs-varid'>rightCoercionTyConKey</span> <span class='hs-varid'>rightCoercionTyCon</span>
<a name="line-523"></a><a name="instCoercionTyConName"></a><span class='hs-definition'>instCoercionTyConName</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoConName</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsLit</span> <span class='hs-str'>"inst"</span><span class='hs-layout'>)</span> <span class='hs-varid'>instCoercionTyConKey</span> <span class='hs-varid'>instCoercionTyCon</span>
<a name="line-524"></a><a name="unsafeCoercionTyConName"></a><span class='hs-definition'>unsafeCoercionTyConName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkCoConName</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsLit</span> <span class='hs-str'>"CoUnsafe"</span><span class='hs-layout'>)</span> <span class='hs-varid'>unsafeCoercionTyConKey</span> <span class='hs-varid'>unsafeCoercionTyCon</span>
<a name="line-525"></a>
<a name="line-526"></a>
<a name="line-527"></a>
<a name="line-528"></a><a name="instNewTyCon_maybe"></a><span class='hs-definition'>instNewTyCon_maybe</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-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoercionI</span><span class='hs-layout'>)</span>
<a name="line-529"></a><span class='hs-comment'>-- ^ If @co :: T ts ~ rep_ty@ then:</span>
<a name="line-530"></a><span class='hs-comment'>--</span>
<a name="line-531"></a><span class='hs-comment'>-- &gt; instNewTyCon_maybe T ts = Just (rep_ty, co)</span>
<a name="line-532"></a><span class='hs-definition'>instNewTyCon_maybe</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>tys</span>
<a name="line-533"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span> <span class='hs-varid'>mb_co_tc</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>unwrapNewTyCon_maybe</span> <span class='hs-varid'>tc</span>
<a name="line-534"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>tys</span> <span class='hs-varop'>`lengthIs`</span> <span class='hs-varid'>tyConArity</span> <span class='hs-varid'>tc</span> <span class='hs-layout'>)</span>
<a name="line-535"></a>    <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTyWith</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>tys</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span> 
<a name="line-536"></a>	  <span class='hs-keyword'>case</span> <span class='hs-varid'>mb_co_tc</span> <span class='hs-keyword'>of</span>
<a name="line-537"></a>	   <span class='hs-conid'>Nothing</span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IdCo</span>
<a name="line-538"></a>	   <span class='hs-conid'>Just</span> <span class='hs-varid'>co_tc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ACo</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkTyConApp</span> <span class='hs-varid'>co_tc</span> <span class='hs-varid'>tys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-539"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-540"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-541"></a>
<a name="line-542"></a><a name="splitNewTypeRepCo_maybe"></a><span class='hs-comment'>-- this is here to avoid module loops</span>
<a name="line-543"></a><span class='hs-definition'>splitNewTypeRepCo_maybe</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span> <span class='hs-conid'>Coercion</span><span class='hs-layout'>)</span>  
<a name="line-544"></a><span class='hs-comment'>-- ^ Sometimes we want to look through a @newtype@ and get its associated coercion.</span>
<a name="line-545"></a><span class='hs-comment'>-- This function only strips *one layer* of @newtype@ off, so the caller will usually call</span>
<a name="line-546"></a><span class='hs-comment'>-- itself recursively. Furthermore, this function should only be applied to types of kind @*@,</span>
<a name="line-547"></a><span class='hs-comment'>-- hence the newtype is always saturated. If @co : ty ~ ty'@ then:</span>
<a name="line-548"></a><span class='hs-comment'>--</span>
<a name="line-549"></a><span class='hs-comment'>-- &gt; splitNewTypeRepCo_maybe ty = Just (ty', co)</span>
<a name="line-550"></a><span class='hs-comment'>--</span>
<a name="line-551"></a><span class='hs-comment'>-- The function returns @Nothing@ for non-@newtypes@ or fully-transparent @newtype@s.</span>
<a name="line-552"></a><span class='hs-definition'>splitNewTypeRepCo_maybe</span> <span class='hs-varid'>ty</span> 
<a name="line-553"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>ty'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>coreView</span> <span class='hs-varid'>ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitNewTypeRepCo_maybe</span> <span class='hs-varid'>ty'</span>
<a name="line-554"></a><span class='hs-definition'>splitNewTypeRepCo_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>tys</span><span class='hs-layout'>)</span>
<a name="line-555"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty'</span><span class='hs-layout'>,</span> <span class='hs-varid'>coi</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>instNewTyCon_maybe</span> <span class='hs-varid'>tc</span> <span class='hs-varid'>tys</span>
<a name="line-556"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>coi</span> <span class='hs-keyword'>of</span>
<a name="line-557"></a>	<span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>ty'</span><span class='hs-layout'>,</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-558"></a>	<span class='hs-conid'>IdCo</span>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"splitNewTypeRepCo_maybe"</span>
<a name="line-559"></a>			<span class='hs-comment'>-- This case handled by coreView</span>
<a name="line-560"></a><span class='hs-definition'>splitNewTypeRepCo_maybe</span> <span class='hs-keyword'>_</span>
<a name="line-561"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-562"></a>
<a name="line-563"></a><a name="coreEqCoercion"></a><span class='hs-comment'>-- | Determines syntactic equality of coercions</span>
<a name="line-564"></a><span class='hs-definition'>coreEqCoercion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-565"></a><span class='hs-definition'>coreEqCoercion</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coreEqType</span>
</pre>\end{code}


--------------------------------------
-- CoercionI smart constructors
--	lifted smart constructors of ordinary coercions

\begin{code}
<pre><a name="line-1"></a><a name="CoercionI"></a><span class='hs-comment'>-- | 'CoercionI' represents a /lifted/ ordinary 'Coercion', in that it</span>
<a name="line-2"></a><a name="CoercionI"></a><span class='hs-comment'>-- can represent either one of:</span>
<a name="line-3"></a><a name="CoercionI"></a><span class='hs-comment'>--</span>
<a name="line-4"></a><a name="CoercionI"></a><span class='hs-comment'>-- 1. A proper 'Coercion'</span>
<a name="line-5"></a><a name="CoercionI"></a><span class='hs-comment'>--</span>
<a name="line-6"></a><a name="CoercionI"></a><span class='hs-comment'>-- 2. The identity coercion</span>
<a name="line-7"></a><a name="CoercionI"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ACo</span> <span class='hs-conid'>Coercion</span>
<a name="line-8"></a>
<a name="line-9"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Outputable</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyword'>where</span>
<a name="line-10"></a>  <span class='hs-varid'>ppr</span> <span class='hs-conid'>IdCo</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>"IdCo"</span><span class='hs-layout'>)</span>
<a name="line-11"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>co</span>
<a name="line-12"></a>
<a name="line-13"></a><a name="isIdentityCoI"></a><span class='hs-definition'>isIdentityCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-14"></a><span class='hs-definition'>isIdentityCoI</span> <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-15"></a><span class='hs-definition'>isIdentityCoI</span> <span class='hs-keyword'>_</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-16"></a>
<a name="line-17"></a><a name="allIdCoIs"></a><span class='hs-comment'>-- | Tests whether all the given 'CoercionI's represent the identity coercion</span>
<a name="line-18"></a><span class='hs-definition'>allIdCoIs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoercionI</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-19"></a><span class='hs-definition'>allIdCoIs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>all</span> <span class='hs-varid'>isIdentityCoI</span>
<a name="line-20"></a>
<a name="line-21"></a><a name="zipCoArgs"></a><span class='hs-comment'>-- | For each 'CoercionI' in the input list, return either the 'Coercion' it</span>
<a name="line-22"></a><span class='hs-comment'>-- contains or the corresponding 'Type' from the other list</span>
<a name="line-23"></a><span class='hs-definition'>zipCoArgs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoercionI</span><span class='hs-keyglyph'>]</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'>Coercion</span><span class='hs-keyglyph'>]</span>
<a name="line-24"></a><span class='hs-definition'>zipCoArgs</span> <span class='hs-varid'>cois</span> <span class='hs-varid'>tys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>zipWith</span> <span class='hs-varid'>fromCoI</span> <span class='hs-varid'>cois</span> <span class='hs-varid'>tys</span>
<a name="line-25"></a>
<a name="line-26"></a><a name="fromCoI"></a><span class='hs-comment'>-- | Return either the 'Coercion' contained within the 'CoercionI' or the given</span>
<a name="line-27"></a><span class='hs-comment'>-- 'Type' if the 'CoercionI' is the identity 'Coercion'</span>
<a name="line-28"></a><span class='hs-definition'>fromCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span>
<a name="line-29"></a><span class='hs-definition'>fromCoI</span> <span class='hs-conid'>IdCo</span> <span class='hs-varid'>ty</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ty</span>	<span class='hs-comment'>-- Identity coercion represented </span>
<a name="line-30"></a><span class='hs-definition'>fromCoI</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>co</span>	<span class='hs-comment'>-- 	by the type itself</span>
<a name="line-31"></a>
<a name="line-32"></a><a name="mkSymCoI"></a><span class='hs-comment'>-- | Smart constructor for @sym@ on 'CoercionI', see also 'mkSymCoercion'</span>
<a name="line-33"></a><span class='hs-definition'>mkSymCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-34"></a><span class='hs-definition'>mkSymCoI</span> <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-35"></a><span class='hs-definition'>mkSymCoI</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkCoercion</span> <span class='hs-varid'>symCoercionTyCon</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>co</span><span class='hs-keyglyph'>]</span> 
<a name="line-36"></a>				<span class='hs-comment'>-- the smart constructor</span>
<a name="line-37"></a>				<span class='hs-comment'>-- is too smart with tyvars</span>
<a name="line-38"></a>
<a name="line-39"></a><a name="mkTransCoI"></a><span class='hs-comment'>-- | Smart constructor for @trans@ on 'CoercionI', see also 'mkTransCoercion'</span>
<a name="line-40"></a><span class='hs-definition'>mkTransCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-41"></a><span class='hs-definition'>mkTransCoI</span> <span class='hs-conid'>IdCo</span> <span class='hs-varid'>aco</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>aco</span>
<a name="line-42"></a><span class='hs-definition'>mkTransCoI</span> <span class='hs-varid'>aco</span> <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>aco</span>
<a name="line-43"></a><span class='hs-definition'>mkTransCoI</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkTransCoercion</span> <span class='hs-varid'>co1</span> <span class='hs-varid'>co2</span>
<a name="line-44"></a>
<a name="line-45"></a><a name="mkTyConAppCoI"></a><span class='hs-comment'>-- | Smart constructor for type constructor application on 'CoercionI', see also 'mkAppCoercion'</span>
<a name="line-46"></a><span class='hs-definition'>mkTyConAppCoI</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'>CoercionI</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-47"></a><span class='hs-definition'>mkTyConAppCoI</span> <span class='hs-varid'>tyCon</span> <span class='hs-varid'>tys</span> <span class='hs-varid'>cois</span>
<a name="line-48"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>allIdCoIs</span> <span class='hs-varid'>cois</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-49"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>	   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-layout'>(</span><span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tyCon</span> <span class='hs-layout'>(</span><span class='hs-varid'>zipCoArgs</span> <span class='hs-varid'>cois</span> <span class='hs-varid'>tys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-50"></a>
<a name="line-51"></a><a name="mkAppTyCoI"></a><span class='hs-comment'>-- | Smart constructor for honest-to-god 'Coercion' application on 'CoercionI', see also 'mkAppCoercion'</span>
<a name="line-52"></a><span class='hs-definition'>mkAppTyCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-53"></a><span class='hs-definition'>mkAppTyCoI</span> <span class='hs-keyword'>_</span>   <span class='hs-conid'>IdCo</span> <span class='hs-keyword'>_</span>   <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-54"></a><span class='hs-definition'>mkAppTyCoI</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>coi1</span> <span class='hs-varid'>ty2</span> <span class='hs-varid'>coi2</span> <span class='hs-keyglyph'>=</span>
<a name="line-55"></a>	<span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>AppTy</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromCoI</span> <span class='hs-varid'>coi1</span> <span class='hs-varid'>ty1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromCoI</span> <span class='hs-varid'>coi2</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-56"></a>
<a name="line-57"></a><a name="mkFunTyCoI"></a><span class='hs-comment'>-- | Smart constructor for function-'Coercion's on 'CoercionI', see also 'mkFunCoercion'</span>
<a name="line-58"></a><span class='hs-definition'>mkFunTyCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-59"></a><span class='hs-definition'>mkFunTyCoI</span> <span class='hs-keyword'>_</span>   <span class='hs-conid'>IdCo</span> <span class='hs-keyword'>_</span>   <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-60"></a><span class='hs-definition'>mkFunTyCoI</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>coi1</span> <span class='hs-varid'>ty2</span> <span class='hs-varid'>coi2</span> <span class='hs-keyglyph'>=</span>
<a name="line-61"></a>	<span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>FunTy</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromCoI</span> <span class='hs-varid'>coi1</span> <span class='hs-varid'>ty1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromCoI</span> <span class='hs-varid'>coi2</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
<a name="line-62"></a>
<a name="line-63"></a><a name="mkForAllTyCoI"></a><span class='hs-comment'>-- | Smart constructor for quantified 'Coercion's on 'CoercionI', see also 'mkForAllCoercion'</span>
<a name="line-64"></a><span class='hs-definition'>mkForAllTyCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TyVar</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-65"></a><span class='hs-definition'>mkForAllTyCoI</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>IdCo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-66"></a><span class='hs-definition'>mkForAllTyCoI</span> <span class='hs-varid'>tv</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>ForAllTy</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>co</span>
<a name="line-67"></a>
<a name="line-68"></a><a name="fromACo"></a><span class='hs-comment'>-- | Extract a 'Coercion' from a 'CoercionI' if it represents one. If it is the identity coercion,</span>
<a name="line-69"></a><span class='hs-comment'>-- panic</span>
<a name="line-70"></a><span class='hs-definition'>fromACo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Coercion</span>
<a name="line-71"></a><span class='hs-definition'>fromACo</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>co</span>
<a name="line-72"></a>
<a name="line-73"></a><a name="mkClassPPredCoI"></a><span class='hs-comment'>-- | Smart constructor for class 'Coercion's on 'CoercionI'. Satisfies:</span>
<a name="line-74"></a><span class='hs-comment'>--</span>
<a name="line-75"></a><span class='hs-comment'>-- &gt; mkClassPPredCoI cls tys cois :: PredTy (cls tys) ~ PredTy (cls (tys `cast` cois))</span>
<a name="line-76"></a><span class='hs-definition'>mkClassPPredCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Class</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'>CoercionI</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-77"></a><span class='hs-definition'>mkClassPPredCoI</span> <span class='hs-varid'>cls</span> <span class='hs-varid'>tys</span> <span class='hs-varid'>cois</span> 
<a name="line-78"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>allIdCoIs</span> <span class='hs-varid'>cois</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-79"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>PredTy</span> <span class='hs-varop'>$</span> <span class='hs-conid'>ClassP</span> <span class='hs-varid'>cls</span> <span class='hs-layout'>(</span><span class='hs-varid'>zipCoArgs</span> <span class='hs-varid'>cois</span> <span class='hs-varid'>tys</span><span class='hs-layout'>)</span>
<a name="line-80"></a>
<a name="line-81"></a><a name="mkIParamPredCoI"></a><span class='hs-comment'>-- | Smart constructor for implicit parameter 'Coercion's on 'CoercionI'. Similar to 'mkClassPPredCoI'</span>
<a name="line-82"></a><span class='hs-definition'>mkIParamPredCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>IPName</span> <span class='hs-conid'>Name</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> 
<a name="line-83"></a><span class='hs-definition'>mkIParamPredCoI</span> <span class='hs-keyword'>_</span>   <span class='hs-conid'>IdCo</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-84"></a><span class='hs-definition'>mkIParamPredCoI</span> <span class='hs-varid'>ipn</span> <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>PredTy</span> <span class='hs-varop'>$</span> <span class='hs-conid'>IParam</span> <span class='hs-varid'>ipn</span> <span class='hs-varid'>co</span>
<a name="line-85"></a>
<a name="line-86"></a><a name="mkEqPredCoI"></a><span class='hs-comment'>-- | Smart constructor for type equality 'Coercion's on 'CoercionI'. Similar to 'mkClassPPredCoI'</span>
<a name="line-87"></a><span class='hs-definition'>mkEqPredCoI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoercionI</span>
<a name="line-88"></a><span class='hs-definition'>mkEqPredCoI</span> <span class='hs-keyword'>_</span>    <span class='hs-conid'>IdCo</span>     <span class='hs-keyword'>_</span>   <span class='hs-conid'>IdCo</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdCo</span>
<a name="line-89"></a><span class='hs-definition'>mkEqPredCoI</span> <span class='hs-varid'>ty1</span>  <span class='hs-conid'>IdCo</span>     <span class='hs-keyword'>_</span>   <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>PredTy</span> <span class='hs-varop'>$</span> <span class='hs-conid'>EqPred</span> <span class='hs-varid'>ty1</span> <span class='hs-varid'>co2</span>
<a name="line-90"></a><span class='hs-definition'>mkEqPredCoI</span> <span class='hs-keyword'>_</span>   <span class='hs-layout'>(</span><span class='hs-conid'>ACo</span> <span class='hs-varid'>co1</span><span class='hs-layout'>)</span> <span class='hs-varid'>ty2</span> <span class='hs-varid'>coi2</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ACo</span> <span class='hs-varop'>$</span> <span class='hs-conid'>PredTy</span> <span class='hs-varop'>$</span> <span class='hs-conid'>EqPred</span> <span class='hs-varid'>co1</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromCoI</span> <span class='hs-varid'>coi2</span> <span class='hs-varid'>ty2</span><span class='hs-layout'>)</span>
</pre>\end{code}
</body>
</html>