Skip to content

Instantly share code, notes, and snippets.

@michaelt
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelt/08160822524b4a0a3bb6 to your computer and use it in GitHub Desktop.
Save michaelt/08160822524b4a0a3bb6 to your computer and use it in GitHub Desktop.
DataHinds syntax highlighting
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<style type="text/css">code{white-space: pre;}</style>
<style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
</style>
</head>
<body>
<pre class="sourceCode haskell"><code class="sourceCode haskell">
<span class="ot">{-# OPTIONS_GHC -fno-warn-dodgy-exports #-}</span>
<span class="co">{- | an incomplete extension of dimensional-tf to work with hmatrix and ad</span>
<span class="co">Haddocks are organized to follow hmatrix</span>
<span class="co">note: for subscripting, use the &#39;HNat&#39; while the units still use &#39;N.NumType&#39;</span>
<span class="co">TODO:</span>
<span class="co">* Friendly syntax for introduction (more matD)</span>
<span class="co">* Friendly syntax for elimination (matD as pattern)</span>
<span class="co">* A pretty-printer that multiplies out the dimensions at each place?</span>
<span class="co"> The current show instance makes you mentally multiply out row and column units</span>
<span class="co"> (which helps you to see the big picture, but may be more work in other cases)</span>
<span class="co">* check that all types that could could be inferred are</span>
<span class="co">* default columns/rows to dimensionless?</span>
<span class="co">* missing operations (check export list comments)</span>
<span class="co">-}</span>
<span class="kw">module</span> <span class="dt">DimMat.Internal</span> <span class="kw">where</span>
<span class="kw">import </span><span class="dt">Foreign.Storable</span> (<span class="dt">Storable</span>)
<span class="kw">import </span><span class="dt">GHC.Exts</span> (<span class="dt">Constraint</span>)
<span class="kw">import </span><span class="dt">Data.Type.Equality</span> (type (==))
<span class="kw">import qualified</span> <span class="dt">Prelude</span> <span class="kw">as</span> <span class="dt">P</span>
<span class="kw">import </span><span class="dt">Prelude</span> (<span class="dt">Double</span>)
<span class="kw">import </span><span class="dt">Numeric.Units.Dimensional</span> <span class="kw">hiding</span> (<span class="dt">Mul</span>, <span class="dt">Div</span>)
<span class="kw">import </span><span class="dt">Numeric.Units.Dimensional.Prelude</span> <span class="kw">hiding</span> (<span class="dt">Mul</span>, <span class="dt">Div</span>)
<span class="kw">import qualified</span> <span class="dt">Numeric.Units.Dimensional</span> <span class="kw">as</span> <span class="dt">D</span>
<span class="kw">import qualified</span> <span class="dt">Numeric.LinearAlgebra</span> <span class="kw">as</span> <span class="dt">H</span>
<span class="kw">import qualified</span> <span class="dt">Numeric.LinearAlgebra.LAPACK</span> <span class="kw">as</span> <span class="dt">H</span>
<span class="kw">import </span><span class="dt">Text.PrettyPrint.ANSI.Leijen</span>
<span class="kw">import </span><span class="dt">Data.List</span> (transpose)
<span class="kw">import </span><span class="dt">Data.HList.CommonMain</span> <span class="kw">hiding</span> (<span class="dt">MapFst</span>)
<span class="co">-- * Replacements for Dimensional classes</span>
<span class="co">-- | a version of Numeric.Units.Dimensional.&#39;D.Mul&#39; which</span>
<span class="co">-- requires the arguments to include the &#39;D.Dim&#39; type constructor</span>
<span class="kw">class</span> (<span class="dt">D.Mul</span> a b c) <span class="ot">=&gt;</span> <span class="dt">Mul</span> a b c
<span class="kw">instance</span> (<span class="dt">D.Mul</span> a b c,
a <span class="fu">~</span> <span class="dt">Dim</span> l m t i th n j,
b <span class="fu">~</span> <span class="dt">Dim</span> l&#39; m&#39; t&#39; i&#39; th&#39; n&#39; j&#39;,
c <span class="fu">~</span> <span class="dt">Dim</span> l&#39;&#39; m&#39;&#39; t&#39;&#39; i&#39;&#39; th&#39;&#39; n&#39;&#39; j&#39;&#39;) <span class="ot">=&gt;</span>
<span class="dt">Mul</span> a b c
<span class="co">-- | a version of Numeric.Units.Dimensional.&#39;D.Div&#39; which</span>
<span class="co">-- requires the arguments to include the &#39;D.Dim&#39; type constructor</span>
<span class="kw">class</span> (<span class="dt">D.Div</span> a b c) <span class="ot">=&gt;</span> <span class="dt">Div</span> a b c
<span class="kw">instance</span> (<span class="dt">D.Div</span> a b c,
a <span class="fu">~</span> <span class="dt">Dim</span> l m t i th n j,
b <span class="fu">~</span> <span class="dt">Dim</span> l&#39; m&#39; t&#39; i&#39; th&#39; n&#39; j&#39;,
c <span class="fu">~</span> <span class="dt">Dim</span> l&#39;&#39; m&#39;&#39; t&#39;&#39; i&#39;&#39; th&#39;&#39; n&#39;&#39; j&#39;&#39;) <span class="ot">=&gt;</span>
<span class="dt">Div</span> a b c
<span class="co">-- * AD</span>
<span class="st">#ifdef WITH_AD</span>
<span class="co">{- |</span>
<span class="co">&gt;&gt;&gt; let ke velocity = velocity*velocity*(1*~kilo gram)</span>
<span class="co">&gt;&gt;&gt; diff ke (3 *~ (metre/second))</span>
<span class="co">6.0 m^-1 kg^-1 s</span>
<span class="co">-}</span>
<span class="ot">diff ::</span> (<span class="dt">Num</span> a) <span class="ot">=&gt;</span>
(forall s<span class="fu">.</span> <span class="dt">AD.Mode</span> s <span class="ot">=&gt;</span> <span class="dt">Dimensional</span> v x (<span class="dt">AD.AD</span> s a)
<span class="ot">-&gt;</span> <span class="dt">Dimensional</span> v y (<span class="dt">AD.AD</span> s a))
<span class="ot">-&gt;</span> <span class="dt">Dimensional</span> v x a <span class="ot">-&gt;</span> <span class="dt">Dimensional</span> v (<span class="dt">Div</span> x y) a
diff f z <span class="fu">=</span> <span class="dt">Dimensional</span> <span class="fu">$</span> AD.diff (unD <span class="fu">.</span> f <span class="fu">.</span> <span class="dt">Dimensional</span>) (unD z)
<span class="kw">where</span> unD (<span class="dt">Dimensional</span> a) <span class="fu">=</span> a
<span class="st">#endif</span>
<span class="co">{- $ad</span>
<span class="co">TODO: gradients, hessians, etc.</span>
<span class="co">Types for derivative towers can see hlist&#39;s @HList\/Data\/HList\/broken\/Lazy.hs@,</span>
<span class="co">but laziness doesn&#39;t really make much sense if the @take@ that is eventually used</span>
<span class="co">to get a finite list for printing etc.</span>
<span class="co">Complications include the fact that AD.grad needs a traversable,</span>
<span class="co">but hmatrix stuff is not traversable (due needing Storable). In ipopt-hs</span>
<span class="co">I got around this problem by copying data. Perhaps that is the solution?</span>
<span class="co">&gt; BROKEN</span>
<span class="co">&gt; grad :: (Num a, AreRecips i iinv, H.Element a, Storable a,</span>
<span class="co">&gt; MapMultEq o iinv r) =&gt;</span>
<span class="co">&gt; (forall s. (AD.Mode s, H.Container H.Vector (AD.AD s a),</span>
<span class="co">&gt; Storable (AD.AD s a), H.Field (AD.AD s a))</span>
<span class="co">&gt; =&gt; DimMat &#39;[i] (AD.AD s a)</span>
<span class="co">&gt; -&gt; Quantity o (AD.AD s a))</span>
<span class="co">&gt; -&gt; DimMat &#39;[i] a</span>
<span class="co">&gt; -&gt; DimMat &#39;[r] a</span>
<span class="co">&gt; grad f (DimVec x) = DimMat (H.fromLists [AD.grad (unQty . f . DimVec . H.fromList) (H.toList x)])</span>
<span class="co">&gt; where unQty (Dimensional a) = a</span>
<span class="co">-}</span>
<span class="co">-- * GADT for linear algebra with units</span>
<span class="co">{- | Generalization of &#39;Dimensional&#39; to matrices and vectors. Units</span>
<span class="co">in each coordinate are known at compile-time. This wraps up HMatrix.</span>
<span class="co">-}</span>
<span class="kw">data</span> <span class="dt">D</span> (<span class="ot">sh ::</span> ( <span class="fu">*</span>, [[ <span class="fu">*</span> ]])) e <span class="kw">where</span>
<span class="dt">DMat</span><span class="ot"> ::</span> (<span class="dt">H.Container</span> <span class="dt">H.Matrix</span> e, <span class="dt">H.Field</span> e)
<span class="ot">=&gt;</span> <span class="dt">H.Matrix</span> e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1,[r, c]) e</span>
<span class="co">-- ^ the units at coordinate i,j are</span>
<span class="co">-- @(r1 &#39;: r)_i (DOne &#39;: c)_j@</span>
<span class="dt">DVec</span><span class="ot"> ::</span> (<span class="dt">H.Container</span> <span class="dt">H.Vector</span> e, <span class="dt">H.Field</span> e)
<span class="ot">=&gt;</span> <span class="dt">H.Vector</span> e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1, &#39;</span>[r]) e
<span class="co">-- ^ the units at coordinate i are</span>
<span class="co">-- @(r1 &#39;: r)_i@</span>
<span class="dt">DScal</span><span class="ot"> ::</span> (<span class="dt">H.Field</span> e) <span class="ot">=&gt;</span> e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1,&#39;</span>[]) e
<span class="co">-- ^ the same as Dimensional</span>
<span class="kw">instance</span> (<span class="dt">Show</span> a, <span class="dt">PPUnits</span> sh) <span class="ot">=&gt;</span> <span class="dt">Pretty</span> (<span class="dt">D</span> sh a) <span class="kw">where</span>
pretty (<span class="dt">DVec</span> v) <span class="fu">=</span> <span class="kw">case</span> ppUnits (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> sh) <span class="kw">of</span>
[rs] <span class="ot">-&gt;</span> vcat
[ dullgreen (string label) <span class="fu">&lt;+&gt;</span> string (show e)
<span class="fu">|</span> (e,label) <span class="ot">&lt;-</span> H.toList v <span class="ot">`zip`</span> pad rs ]
pretty (<span class="dt">DMat</span> m) <span class="fu">=</span> <span class="kw">case</span> ppUnits (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> sh) <span class="kw">of</span>
[rs,cs] <span class="ot">-&gt;</span>
vcat <span class="fu">$</span>
map (hsep <span class="fu">.</span> onHead dullgreen) <span class="fu">$</span>
transpose <span class="fu">$</span> map (onHead dullgreen <span class="fu">.</span> map string <span class="fu">.</span> pad) <span class="fu">$</span>
zipWith (\a b <span class="ot">-&gt;</span> a<span class="fu">:</span>b)
((show (H.rows m) <span class="fu">++</span> <span class="st">&quot;&gt;&lt;&quot;</span><span class="fu">++</span> show (H.cols m)) <span class="fu">:</span> cs) <span class="fu">$</span>
transpose <span class="fu">$</span>
zipWith (\r e <span class="ot">-&gt;</span> r <span class="fu">:</span> map show e) rs (H.toLists m)
<span class="kw">where</span>
onHead f (x<span class="fu">:</span>xs) <span class="fu">=</span> f x <span class="fu">:</span> xs
onHead _ [] <span class="fu">=</span> []
<span class="kw">instance</span> <span class="dt">Pretty</span> (<span class="dt">D</span> sh a) <span class="ot">=&gt;</span> <span class="dt">Show</span> (<span class="dt">D</span> sh a) <span class="kw">where</span>
showsPrec p x <span class="fu">=</span> showsPrec p (pretty x)
<span class="co">-- ** pretty instance</span>
<span class="ot">pad ::</span> [<span class="dt">String</span>] <span class="ot">-&gt;</span> [<span class="dt">String</span>]
pad [] <span class="fu">=</span> []
pad xs <span class="fu">=</span> <span class="kw">let</span>
w <span class="fu">=</span> maximum (map length xs)
<span class="kw">in</span> map (\x <span class="ot">-&gt;</span> take w <span class="fu">$</span> x <span class="fu">++</span> replicate w <span class="ch">&#39; &#39;</span>) xs
<span class="kw">class</span> <span class="dt">PPUnits</span> (<span class="ot">sh ::</span> k) <span class="kw">where</span>
<span class="ot"> ppUnits ::</span> <span class="dt">Proxy</span> sh <span class="ot">-&gt;</span> [[<span class="dt">String</span>]]
<span class="kw">instance</span> forall (<span class="ot">r1 ::</span> <span class="fu">*</span>) (<span class="ot">r::</span>[<span class="fu">*</span>]) (<span class="ot">c ::</span> [<span class="fu">*</span>]) l m t i th n j<span class="fu">.</span>
(<span class="dt">PPUnits</span> [r1 <span class="ch">&#39;: r, c], Show (Quantity r1 Int), PPUnits&#39;</span> c, <span class="dt">PPUnits&#39;</span> r,
r1 <span class="fu">~</span> <span class="dt">Dim</span> l m t i th n j) <span class="ot">=&gt;</span> <span class="dt">PPUnits</span> <span class="ch">&#39;(r1, [r,c]) where</span>
ppUnits _ <span class="fu">=</span> ppUnits (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> [r1 <span class="ch">&#39;: r, DOne &#39;</span><span class="fu">:</span> c])
<span class="kw">instance</span> (<span class="dt">PPUnits&#39;</span> x, <span class="dt">PPUnits</span> xs) <span class="ot">=&gt;</span> <span class="dt">PPUnits</span> (x <span class="ch">&#39;: xs) where</span>
ppUnits _ <span class="fu">=</span> ppUnits&#39; (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> x) <span class="fu">:</span> ppUnits (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> xs)
<span class="kw">instance</span> <span class="dt">PPUnits</span> <span class="ch">&#39;[] where</span>
ppUnits _ <span class="fu">=</span> []
<span class="kw">class</span> <span class="dt">PPUnits&#39;</span> (<span class="ot">sh ::</span> [ <span class="fu">*</span> ]) <span class="kw">where</span>
<span class="ot"> ppUnits&#39; ::</span> <span class="dt">Proxy</span> sh <span class="ot">-&gt;</span> [<span class="dt">String</span>]
<span class="kw">instance</span> (<span class="dt">PPUnits&#39;</span> xs) <span class="ot">=&gt;</span> <span class="dt">PPUnits&#39;</span> (<span class="dt">DOne</span> <span class="ch">&#39;: xs) where</span>
ppUnits&#39; _ <span class="fu">=</span> <span class="st">&quot;1&quot;</span> <span class="fu">:</span> ppUnits&#39; (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> xs)
<span class="kw">instance</span> (<span class="dt">ShowDimSpec</span> x, <span class="dt">PPUnits&#39;</span> xs) <span class="ot">=&gt;</span> <span class="dt">PPUnits&#39;</span> (x <span class="ch">&#39;: xs) where</span>
ppUnits&#39; _ <span class="fu">=</span> showDimSpec (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> x) <span class="fu">:</span> ppUnits&#39; (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> xs)
<span class="kw">instance</span> <span class="dt">PPUnits&#39;</span> <span class="ch">&#39;[] where</span>
ppUnits&#39; _ <span class="fu">=</span> []
<span class="kw">class</span> <span class="dt">ShowDimSpec</span> a <span class="kw">where</span>
<span class="ot"> showDimSpec ::</span> <span class="dt">Proxy</span> a <span class="ot">-&gt;</span> <span class="dt">String</span>
<span class="kw">instance</span> (<span class="dt">Show</span> (<span class="dt">Quantity</span> a <span class="dt">Int</span>), <span class="dt">Dim</span> l m t i th n j <span class="fu">~</span> a) <span class="ot">=&gt;</span> <span class="dt">ShowDimSpec</span> a <span class="kw">where</span>
showDimSpec _ <span class="fu">=</span> <span class="kw">case</span> drop <span class="dv">2</span> <span class="fu">$</span> show (<span class="dv">1</span> <span class="fu">*~</span> (<span class="dt">Dimensional</span> <span class="dv">1</span><span class="ot"> ::</span> <span class="dt">Unit</span> a <span class="dt">Int</span>)) <span class="kw">of</span>
<span class="st">&quot;&quot;</span> <span class="ot">-&gt;</span> <span class="st">&quot;1&quot;</span>
x <span class="ot">-&gt;</span> x
<span class="co">-- * Constraints</span>
<span class="co">{- $justification</span>
<span class="co">A major theme in this library is that type inference goes in whichever direction</span>
<span class="co">it can: in ordinary haskell it is very common for argument types to be determined</span>
<span class="co">by the result types. For example see any code that uses &#39;Num&#39; or &#39;Read&#39;.</span>
<span class="co">When we use type families, things look more convenient:</span>
<span class="co">@</span>
<span class="co">data Nat = S Nat | Z</span>
<span class="co">type family Add (a :: Nat) (b :: Nat) :: Nat</span>
<span class="co">type instance Add Z b = b</span>
<span class="co">type instance Add (S a) b = Add a (S b)</span>
<span class="co">@</span>
<span class="co">But ghc is unable to deduce things like @a ~ Z@ given evidence such as @Add Z a ~ Z@.</span>
<span class="co">One way around this is to use @ConstraintKinds@:</span>
<span class="co">@</span>
<span class="co">type AddT (a :: Nat) (b :: Nat) (c :: Nat)</span>
<span class="co"> = (Add a b ~ c, Sub c a ~ b, Sub c b ~ a)</span>
<span class="co">@</span>
<span class="co">Which leads to functions like @f :: AddT a b ab =&gt; ... @. This is bad for a couple reasons:</span>
<span class="co">* the right-hand-side of the type can only mention type variables on the</span>
<span class="co"> left-hand-side.</span>
<span class="co">* the left hand side can only bind type variables. Working around this</span>
<span class="co"> leads to many auxiliary type families such as Fst, Snd and Head, or</span>
<span class="co"> leads to a @type family AddT@</span>
<span class="co">So below many constraints expressed as classes, since they have less</span>
<span class="co">of those limitations.</span>
<span class="co">-}</span>
<span class="co">-- | @a*b = c@ when any are lists</span>
<span class="kw">class</span> <span class="dt">MultEq</span> (<span class="ot">a ::</span> k1) (<span class="ot">b ::</span> k2) (<span class="ot">c ::</span> k3)
<span class="co">-- instance (Zip3 MultEq aas bbs ccs) =&gt; MultEq aas bbs ccs</span>
<span class="kw">instance</span> <span class="dt">Zip3</span> <span class="dt">Mul</span> as bs cs <span class="ot">=&gt;</span> <span class="dt">MultEq</span> as bs cs
<span class="kw">instance</span> <span class="dt">Zip1</span> <span class="dt">Mul</span> as b c <span class="ot">=&gt;</span> <span class="dt">MultEq</span> as b c
<span class="kw">instance</span> <span class="dt">Zip1</span> <span class="dt">Mul</span> bs a c <span class="ot">=&gt;</span> <span class="dt">MultEq</span> a bs c
<span class="kw">instance</span> (<span class="dt">Zip1</span> <span class="dt">Mul</span> cs aInv b,
<span class="dt">Mul</span> a aInv <span class="dt">DOne</span>) <span class="ot">=&gt;</span> <span class="dt">MultEq</span> a b cs
<span class="kw">instance</span> (<span class="dt">SameLength</span> as bs,
<span class="dt">Zip2</span> <span class="dt">Mul</span> as bs c) <span class="ot">=&gt;</span> <span class="dt">MultEq</span> as bs c
<span class="kw">instance</span> (<span class="dt">SameLength</span> as cs,
<span class="dt">Zip2</span> <span class="dt">Div</span> as cs bInv,
<span class="dt">Mul</span> b bInv <span class="dt">DOne</span>) <span class="ot">=&gt;</span> <span class="dt">MultEq</span> as b cs
<span class="kw">instance</span> (<span class="dt">Zip2</span> <span class="dt">Div</span> bs cs aInv,
<span class="dt">SameLength</span> bs cs,
<span class="dt">Mul</span> a aInv <span class="dt">DOne</span>) <span class="ot">=&gt;</span> <span class="dt">MultEq</span> a bs cs
<span class="kw">instance</span> <span class="dt">Mul</span> a b c <span class="ot">=&gt;</span> <span class="dt">MultEq</span> a b c
<span class="co">-- ** Zip</span>
<span class="kw">class</span> (<span class="dt">SameLength</span> a b, <span class="dt">SameLength</span> b c) <span class="ot">=&gt;</span>
<span class="dt">Zip3</span>
(<span class="ot">op ::</span> k <span class="ot">-&gt;</span> k <span class="ot">-&gt;</span> k <span class="ot">-&gt;</span> <span class="dt">Constraint</span>)
(<span class="ot">a ::</span> [k])
(<span class="ot">b ::</span> [k])
(<span class="ot">c ::</span> [k])
<span class="kw">instance</span> (<span class="dt">SameLength</span> aas bbs,
<span class="dt">SameLength</span> ccs bbs,
op a b c,
(a <span class="ch">&#39;: as) ~ aas,</span>
(b <span class="ch">&#39;: bs) ~ bbs,</span>
(c <span class="ch">&#39;: cs) ~ ccs,</span>
<span class="dt">Zip3</span> op as bs cs) <span class="ot">=&gt;</span> <span class="dt">Zip3</span> op aas bbs ccs
<span class="kw">instance</span> <span class="dt">Zip3</span> op <span class="ch">&#39;[] &#39;</span>[] <span class="ch">&#39;[]</span>
<span class="kw">class</span> (<span class="dt">SameLength</span> a b) <span class="ot">=&gt;</span>
<span class="dt">Zip2</span>
(<span class="ot">op ::</span> k <span class="ot">-&gt;</span> k <span class="ot">-&gt;</span> k <span class="ot">-&gt;</span> <span class="dt">Constraint</span>)
(<span class="ot">a ::</span> [k])
(<span class="ot">b ::</span> [k])
(<span class="ot">c ::</span> k)
<span class="kw">instance</span> (<span class="dt">SameLength</span> aas bbs,
op a b c,
(a <span class="ch">&#39;: as) ~ aas,</span>
(b <span class="ch">&#39;: bs) ~ bbs,</span>
<span class="dt">Zip2</span> op as bs c) <span class="ot">=&gt;</span> <span class="dt">Zip2</span> op aas bbs c
<span class="kw">instance</span> <span class="dt">Zip2</span> op <span class="ch">&#39;[] &#39;</span>[] c
<span class="kw">class</span> <span class="dt">Zip1</span>
(<span class="ot">op ::</span> k <span class="ot">-&gt;</span> k <span class="ot">-&gt;</span> k <span class="ot">-&gt;</span> <span class="dt">Constraint</span>)
(<span class="ot">a ::</span> [k])
(<span class="ot">b ::</span> k)
(<span class="ot">c ::</span> k)
<span class="kw">instance</span> ((a <span class="ch">&#39;: as) ~ aas,</span>
op a b c,
<span class="dt">Zip1</span> op as b c) <span class="ot">=&gt;</span> <span class="dt">Zip1</span> op aas b c
<span class="kw">instance</span> <span class="dt">Zip1</span> op <span class="ch">&#39;[] b c</span>
<span class="co">{- | given @ijs :: [[Quantity a]]@ (except the : and [] constructors are</span>
<span class="co">actually (,) and (), ie. a HList that doesn&#39;t use the HList constructors),</span>
<span class="co">calculate a @DimMat rowUnits colUnits@, where the outer product of rowUnits</span>
<span class="co">and colUnits gives the units at each index in the ijs. The first element</span>
<span class="co">of colUnits is DOne.</span>
<span class="co">-}</span>
<span class="kw">class</span> (<span class="dt">SameLength</span> a ab) <span class="ot">=&gt;</span> <span class="dt">Outer</span> a b ab
<span class="kw">instance</span> <span class="dt">Outer</span> <span class="ch">&#39;[] b &#39;</span>[]
<span class="kw">instance</span> (<span class="dt">SameLength</span> aas ccs,
(a <span class="ch">&#39;: as) ~ aas,</span>
(c <span class="ch">&#39;: cs) ~ ccs,</span>
<span class="dt">MultEq</span> a b c,
<span class="dt">Outer</span> as b cs)
<span class="ot">=&gt;</span> <span class="dt">Outer</span> aas b ccs
<span class="co">-- * DimMatFromTuple</span>
<span class="kw">class</span> <span class="dt">DimMatFromTuple</span> ijs r1 r c e
<span class="kw">type</span> family <span class="dt">TupleToHListU</span> (<span class="ot">a ::</span> <span class="fu">*</span>)<span class="ot"> ::</span> [<span class="fu">*</span>]
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">TupleToHListU</span> (a, b) <span class="fu">=</span> () <span class="ch">&#39;: TupleToHListU b</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">TupleToHListU</span> () <span class="fu">=</span> <span class="ch">&#39;[]</span>
<span class="kw">type</span> family <span class="dt">TuplesToHListU</span> (<span class="ot">a ::</span> <span class="fu">*</span>)<span class="ot"> ::</span> [[<span class="fu">*</span>]]
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">TuplesToHListU</span> (a, b) <span class="fu">=</span> <span class="dt">TupleToHListU</span> a <span class="ch">&#39;: TuplesToHListU b </span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">TuplesToHListU</span> () <span class="fu">=</span> <span class="ch">&#39;[]</span>
<span class="kw">instance</span> (<span class="dt">Outer</span> (r1 <span class="ch">&#39;: r) (DOne &#39;</span><span class="fu">:</span> c) ijs&#39;,
<span class="dt">DMFromTuple1</span> e ijs ijs&#39;,
<span class="dt">SameLength</span> (<span class="dt">TuplesToHListU</span> ijs) ijs&#39;) <span class="ot">=&gt;</span> <span class="dt">DimMatFromTuple</span> ijs r1 r c e
<span class="co">-- | helper for &#39;DimMatFromTuple&#39;</span>
<span class="kw">type</span> family <span class="dt">DMFromTuple1</span> e b (<span class="ot">b&#39; ::</span> [[<span class="fu">*</span>]])<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> family <span class="dt">DMFromTuple2</span> e b (<span class="ot">b&#39; ::</span> [<span class="fu">*</span>])<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> family <span class="dt">DMFromTuple3</span> e b<span class="ot"> b&#39; ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DMFromTuple3</span> e (<span class="dt">Quantity</span> b e&#39;) b&#39; <span class="fu">=</span> (e <span class="fu">~</span> e&#39;, b <span class="fu">~</span> b&#39;)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DMFromTuple1</span> e (x, xs) (x&#39; <span class="ch">&#39;: xs&#39;</span>) <span class="fu">=</span> (<span class="dt">TupleToHListU</span> x <span class="ot">`SameLength`</span> x&#39;,
<span class="dt">DMFromTuple2</span> e x x&#39;, <span class="dt">DMFromTuple1</span> e xs xs&#39;)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DMFromTuple1</span> e () xs <span class="fu">=</span> (xs <span class="fu">~</span> <span class="ch">&#39;[])</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DMFromTuple2</span> e (x, xs) (x&#39; <span class="ch">&#39;: xs&#39;</span>) <span class="fu">=</span> (<span class="dt">DMFromTuple3</span> e x x&#39;, <span class="dt">DMFromTuple2</span> e xs xs&#39;)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DMFromTuple2</span> e () xs <span class="fu">=</span> (xs <span class="fu">~</span> <span class="ch">&#39;[])</span>
<span class="co">-- | just for types produced by the matD quasiquote</span>
<span class="ot">toDM ::</span> <span class="dt">DimMatFromTuple</span> ijs r1 r c e <span class="ot">=&gt;</span> ijs <span class="ot">-&gt;</span> <span class="dt">Proxy</span> (<span class="dt">D</span> <span class="ch">&#39;(r1, [r, c]) e)</span>
toDM _ <span class="fu">=</span> <span class="dt">Proxy</span>
<span class="co">-- | @InnerCxt t a b = t ~ &#39;H.dot&#39; a b@</span>
<span class="kw">type</span> family <span class="dt">InnerCxt</span> (<span class="ot">t ::</span> k) (<span class="ot">a ::</span> [k]) (<span class="ot">b ::</span> [k])<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">InnerCxt</span> t (a <span class="ch">&#39;: as) (b &#39;</span><span class="fu">:</span> bs) <span class="fu">=</span> (<span class="dt">MultEq</span> a b t, <span class="dt">InnerCxt</span> t as bs)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">InnerCxt</span> t <span class="ch">&#39;[] &#39;</span>[] <span class="fu">=</span> ()
<span class="kw">class</span> (<span class="dt">SameLength</span> a b, <span class="dt">InnerCxt</span> c a b) <span class="ot">=&gt;</span> <span class="dt">Inner</span> (<span class="ot">a ::</span> [<span class="fu">*</span>]) (<span class="ot">b ::</span> [<span class="fu">*</span>]) (<span class="ot">c ::</span> <span class="fu">*</span>)
<span class="kw">instance</span> (<span class="dt">SameLength</span> aas bbs, <span class="dt">InnerCxt</span> c aas bbs) <span class="ot">=&gt;</span> <span class="dt">Inner</span> aas bbs c
<span class="co">-- | @ProdEq a b@ is @product a ~ b@</span>
<span class="kw">class</span> <span class="dt">ProdEq</span> a b
<span class="kw">instance</span> (<span class="dt">ProdEq</span> as b&#39;, <span class="dt">Mul</span> a b&#39; b) <span class="ot">=&gt;</span> <span class="dt">ProdEq</span> (a <span class="ch">&#39;: as) b</span>
<span class="kw">instance</span> (dOne <span class="fu">~</span> <span class="dt">DOne</span>) <span class="ot">=&gt;</span> <span class="dt">ProdEq</span> <span class="ch">&#39;[] dOne</span>
<span class="co">-- | @RecipEq a aInv@ is @a*aInv ~ DOne@ (or a list of DOne)</span>
<span class="kw">class</span> <span class="dt">RecipEq</span> (<span class="ot">a ::</span> k) (<span class="ot">aInv ::</span> k)
<span class="kw">instance</span> (<span class="dt">MultEq</span> as aInvs <span class="dt">DOne</span>) <span class="ot">=&gt;</span> <span class="dt">RecipEq</span> as aInvs
<span class="co">-- | @AtEq a n b m c@ calculates @(At a n \`Mult\` At b m) ~ c@,</span>
<span class="co">-- but also can infer part of the `a` if the `b` and `c` are known</span>
<span class="kw">type</span> family <span class="dt">AtEq2</span> (<span class="ot">a ::</span> [k]) (<span class="ot">n ::</span> <span class="dt">HNat</span>) (<span class="ot">b ::</span> [k]) (<span class="ot">m ::</span> <span class="dt">HNat</span>) (<span class="ot">c ::</span> k)<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AtEq2</span> (a <span class="ch">&#39;: as) HZero (b &#39;</span><span class="fu">:</span> bs) <span class="dt">HZero</span> c <span class="fu">=</span> (<span class="dt">MultEq</span> a b c)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AtEq2</span> (a <span class="ch">&#39;: as) (HSucc n) bs m c = AtEq2 as n bs m c</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AtEq2</span> as <span class="dt">HZero</span> (b <span class="ch">&#39;: bs) (HSucc m) c = AtEq2 as HZero bs m c</span>
<span class="kw">type</span> family <span class="dt">AtEq</span> (<span class="ot">a ::</span> [k]) (<span class="ot">n ::</span> <span class="dt">HNat</span>) (<span class="ot">b ::</span> k)<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AtEq</span> (a <span class="ch">&#39;: as) HZero b = (a ~ b)</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AtEq</span> (a <span class="ch">&#39;: as) (HSucc n) b = AtEq as n b</span>
<span class="co">-- | Data.Packed.Vector.&#39;H.@&gt;&#39;</span>
<span class="ot">(@&gt;) ::</span> (<span class="dt">HNat2Integral</span> i, <span class="dt">AtEq</span> r i ri, <span class="dt">MultEq</span> r1 ri u)
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1,&#39;</span>[r]) a
<span class="ot">-&gt;</span> <span class="dt">Proxy</span> i
<span class="ot">-&gt;</span> <span class="dt">Quantity</span> u a
<span class="dt">DVec</span> v <span class="fu">@&gt;</span> i <span class="fu">=</span> <span class="dt">Dimensional</span> (v <span class="fu">H.@&gt;</span> hNat2Integral i)
<span class="co">-- | Data.Packed.Matrix.&#39;H.@@&gt;&#39;</span>
<span class="ot">(@@&gt;) ::</span> (<span class="dt">HNat2Integral</span> i, <span class="dt">HNat2Integral</span> j, <span class="dt">AtEq2</span> (r1 <span class="ch">&#39;: r) i (DOne &#39;</span><span class="fu">:</span> c) j ty)
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1, [r,c]) a</span>
<span class="ot">-&gt;</span> (<span class="dt">Proxy</span> i, <span class="dt">Proxy</span> j)
<span class="ot">-&gt;</span> <span class="dt">Quantity</span> ty a
<span class="dt">DMat</span> m <span class="fu">@@&gt;</span> (i,j) <span class="fu">=</span> <span class="dt">Dimensional</span> (m <span class="fu">H.@@&gt;</span> (hNat2Integral i,hNat2Integral j))
<span class="ot">pnorm ::</span> (<span class="dt">AllEq</span> r1 r, <span class="dt">AllEq</span> <span class="dt">DOne</span> c)
<span class="ot">=&gt;</span> <span class="dt">H.NormType</span> <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1, [r, c]) a -&gt; Quantity r1 (H.RealOf a)</span>
pnorm normType (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">Dimensional</span> (H.pnorm normType a)
<span class="co">{- | @AllEq a xs@ is like @all (all (a==)) xs@, @all (a ==) xs@, @a == xs@:</span>
<span class="co">whichever amount of [ ] is peeled off before making the comparison (with ~)</span>
<span class="co">-}</span>
<span class="kw">class</span> <span class="dt">AllEq</span> (<span class="ot">a ::</span> k1) (<span class="ot">xs ::</span> k2)
<span class="kw">instance</span> (a <span class="fu">~</span> x, <span class="dt">AllEq</span> a xs) <span class="ot">=&gt;</span> <span class="dt">AllEq</span> a (x <span class="ch">&#39;: xs)</span>
<span class="kw">instance</span> <span class="dt">AllEq</span> a <span class="ch">&#39;[]</span>
<span class="kw">instance</span> <span class="dt">AllEq</span> <span class="ch">&#39;[] xs</span>
<span class="kw">instance</span> (<span class="dt">AllEq</span> a xs, <span class="dt">AllEq</span> as xs) <span class="ot">=&gt;</span> <span class="dt">AllEq</span> (a <span class="ch">&#39;: as) xs</span>
<span class="co">{- | @c = a `dot` b@ is one of:</span>
<span class="co">&gt; c_ij = sum_j a_ij b_jk</span>
<span class="co">&gt; c_k = sum_j a_j b_jk</span>
<span class="co">&gt; c_i = sum_j a_ij b_j</span>
<span class="co">&gt; c = sum_j a_j b_j</span>
<span class="co">-}</span>
<span class="kw">class</span> <span class="dt">Dot</span> a b c <span class="kw">where</span>
<span class="ot"> dot ::</span> <span class="dt">H.Element</span> e <span class="ot">=&gt;</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e <span class="ot">-&gt;</span> <span class="dt">D</span> c e
<span class="kw">instance</span>
( <span class="dt">MultEq</span> (a <span class="ch">&#39;: ra) b (c &#39;</span><span class="fu">:</span> rc),
<span class="dt">MultEq</span> ca rb b,
shA <span class="fu">~</span> <span class="ch">&#39;(a,[ra, ca]),</span>
shB <span class="fu">~</span> <span class="ch">&#39;(b, rb &#39;</span><span class="fu">:</span> cb),
shC <span class="fu">~</span> <span class="ch">&#39;(c, rc &#39;</span><span class="fu">:</span> cb))
<span class="ot">=&gt;</span> <span class="dt">Dot</span> shA shB shC <span class="kw">where</span>
dot (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.multiply a b)
dot (<span class="dt">DMat</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> <span class="dt">DVec</span> (H.mXv a b)
<span class="co">{-</span>
<span class="co"> dot (DVec a) (DMat b) = DVec (H.vXm a b)</span>
<span class="co"> dot (DVec a) (DVec b) = DScal (H.dot a b)</span>
<span class="co"> -}</span>
<span class="kw">class</span> <span class="dt">Trans</span> a b <span class="kw">where</span>
<span class="ot"> trans ::</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e
<span class="kw">instance</span> (a <span class="fu">~</span> <span class="ch">&#39;(r1, [x,y]),</span>
b <span class="fu">~</span> <span class="ch">&#39;(r1, [y,x]))</span>
<span class="ot">=&gt;</span> <span class="dt">Trans</span> a b <span class="kw">where</span>
trans (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.trans a)
<span class="co">{- | type for a pseudoinverse (and inverse):</span>
<span class="co">The single instance comes from looking at inverses from a 2x2 matrix (let&#39;s call A):</span>
<span class="co">&gt; a b</span>
<span class="co">&gt; c d</span>
<span class="co">and the inverse * determinant of the original</span>
<span class="co">&gt; d -b</span>
<span class="co">&gt; -c a</span>
<span class="co">In the product A * A^-1 the diagonal is dimensionless (&#39;DOne&#39;).</span>
<span class="co">That happens if the row and column type-level unit lists are reciprocals of</span>
<span class="co">eachother (&#39;AreRecips&#39;), so the constraint on the instance of PInv encodes</span>
<span class="co">this exactly (plus some constraints requiring that sh and sh&#39; are at least</span>
<span class="co">1x1)</span>
<span class="co">-}</span>
<span class="kw">class</span> <span class="dt">PInv</span> a b <span class="kw">where</span>
<span class="ot"> pinv ::</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e
<span class="kw">type</span> family <span class="dt">LengthSndTwo</span> (<span class="ot">a ::</span> k)<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">LengthSndTwo</span> <span class="ch">&#39;(a, as) = SameLength as &#39;</span>[(), ()]
<span class="kw">type</span> <span class="dt">AreRecips</span> a b <span class="fu">=</span> <span class="dt">MultEq</span> a b <span class="dt">DOne</span>
<span class="kw">instance</span> (<span class="dt">MultEq</span> ra cb a,
<span class="dt">MultEq</span> ca rb b,
<span class="dt">AreRecips</span> a b,
bSh <span class="fu">~</span> <span class="ch">&#39;(b, [rb, cb]),</span>
aSh <span class="fu">~</span> <span class="ch">&#39;(a, [ra, ca]))</span>
<span class="ot">=&gt;</span> <span class="dt">PInv</span> aSh bSh <span class="kw">where</span>
pinv (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.pinv a)
<span class="ot">inv ::</span> (<span class="dt">PInv</span> a b,
b <span class="fu">~</span> <span class="ch">&#39;(t1, [t2, t3]))</span>
<span class="ot">=&gt;</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e
inv (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.inv a)
<span class="ot">pinvTol ::</span> (<span class="dt">PInv</span> a b,
<span class="st">#if !MIN_VERSION_hmatrix(0,15,0)</span>
<span class="co">-- on hmatrix 13, the pinvTol function has type Double -&gt; Matrix Double -&gt; MatrixDouble, later they generalized to Field t =&gt; Double -&gt; Matrix t -&gt; Matrix t</span>
a <span class="fu">~</span> <span class="dt">Double</span>,
<span class="st">#endif</span>
b <span class="fu">~</span> <span class="ch">&#39;(t1, [t2, t3]) )</span>
<span class="ot">=&gt;</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e
pinvTol tol (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.pinvTol tol a)
<span class="kw">class</span> <span class="dt">Det</span> a b <span class="kw">where</span>
<span class="ot"> det ::</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">Quantity</span> b e
<span class="kw">instance</span> (<span class="dt">SameLength</span> r c,
<span class="dt">ProdEq</span> (r1 <span class="ch">&#39;: r) (pr :: *),</span>
<span class="dt">ProdEq</span> c (<span class="ot">pc ::</span> <span class="fu">*</span>),
<span class="dt">MultEq</span> pr pc b,
a <span class="fu">~</span> <span class="ch">&#39;(r1, [r, c])) =&gt;</span>
<span class="dt">Det</span> a b <span class="kw">where</span>
det (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">Dimensional</span> (H.det a)
<span class="co">{- | Numeric.LinearAlgebra.Algorithms.&#39;H.expm&#39;</span>
<span class="co">@y t = expm (scale t a) \`multiply\` y0@ solves the DE @y&#39; = Ay@ where y0 is the</span>
<span class="co">value of y at time 0</span>
<span class="co">-}</span>
<span class="ot">expm ::</span> (<span class="dt">AreRecips</span> r c)
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1, [r, c]) a</span>
<span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(r1, [r, c]) a</span>
expm (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.expm a)
<span class="co">{- | Numeric.Container.&#39;H.scale&#39;</span>
<span class="co">-}</span>
<span class="kw">class</span> <span class="dt">Scale</span> a b c <span class="kw">where</span>
<span class="ot"> scale ::</span> <span class="dt">Quantity</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e <span class="ot">-&gt;</span> <span class="dt">D</span> c e
<span class="ot">fromQty ::</span> <span class="dt">H.Field</span> e <span class="ot">=&gt;</span> <span class="dt">Quantity</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e
fromQty (<span class="dt">Dimensional</span> a) <span class="fu">=</span> <span class="dt">DScal</span> a
<span class="ot">toQty ::</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e <span class="ot">-&gt;</span> <span class="dt">Quantity</span> a e
toQty (<span class="dt">DScal</span> a) <span class="fu">=</span> <span class="dt">Dimensional</span> a
<span class="kw">instance</span> (<span class="dt">MultEq</span> a (r1 <span class="ch">&#39;: r) (r1&#39;</span> <span class="ch">&#39;: r&#39;</span>),
b <span class="fu">~</span> <span class="ch">&#39;(r1, r &#39;</span><span class="fu">:</span> rs),
c <span class="fu">~</span> <span class="ch">&#39;(r1&#39;</span>, r&#39; <span class="ch">&#39;: rs)) =&gt;</span>
<span class="dt">Scale</span> a b c <span class="kw">where</span>
scale (<span class="dt">Dimensional</span> t) (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.scale t a)
scale (<span class="dt">Dimensional</span> t) (<span class="dt">DVec</span> a) <span class="fu">=</span> <span class="dt">DVec</span> (H.scale t a)
<span class="co">{- | Numeric.Container.&#39;H.scaleRecip&#39;</span>
<span class="co">-}</span>
<span class="kw">class</span> <span class="dt">ScaleRecip</span> a b c <span class="kw">where</span>
<span class="ot"> scaleRecip ::</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e <span class="ot">-&gt;</span> <span class="dt">D</span> b e <span class="ot">-&gt;</span> <span class="dt">D</span> c e
<span class="kw">class</span> <span class="dt">ScaleRecip1</span> (<span class="ot">bool ::</span> <span class="dt">Bool</span>) a b c <span class="kw">where</span>
<span class="ot"> scaleRecip1 ::</span> <span class="dt">Proxy</span> bool <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e <span class="ot">-&gt;</span> <span class="dt">D</span> b e <span class="ot">-&gt;</span> <span class="dt">D</span> c e
<span class="kw">instance</span>
(<span class="dt">ScaleRecipCxt</span> r1 r1&#39; r r&#39; rs rs&#39; a b c
, rs&#39; <span class="fu">~</span> <span class="ch">&#39;[ t1 ]</span>
) <span class="ot">=&gt;</span> <span class="dt">ScaleRecip1</span> <span class="dt">True</span> a b c <span class="kw">where</span>
scaleRecip1 _ (<span class="dt">DScal</span> t) (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.scaleRecip t a)
<span class="kw">instance</span>
(<span class="dt">ScaleRecipCxt</span> r1 r1&#39; r r&#39; rs rs&#39; a b c,
rs&#39; <span class="fu">~</span> <span class="ch">&#39;[]) =&gt;</span>
<span class="dt">ScaleRecip1</span> <span class="dt">False</span> a b c <span class="kw">where</span>
scaleRecip1 _ (<span class="dt">DScal</span> t) (<span class="dt">DVec</span> a) <span class="fu">=</span> <span class="dt">DVec</span> (H.scaleRecip t a)
<span class="kw">instance</span> (bool1 <span class="fu">~</span> (<span class="dt">HLength</span> bs <span class="fu">==</span> <span class="dt">HSucc</span> (<span class="dt">HSucc</span> <span class="dt">HZero</span>)),
bool2 <span class="fu">~</span> (<span class="dt">HLength</span> cs <span class="fu">==</span> <span class="dt">HSucc</span> (<span class="dt">HSucc</span> <span class="dt">HZero</span>)),
bool1 <span class="fu">~</span> bool2,
<span class="dt">ScaleRecip1</span> bool1 a <span class="ch">&#39;(b, bs) &#39;</span>(c, cs)) <span class="ot">=&gt;</span> <span class="dt">ScaleRecip</span> a <span class="ch">&#39;(b, bs) &#39;</span>(c, cs) <span class="kw">where</span>
scaleRecip <span class="fu">=</span> scaleRecip1 (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> bool1)
<span class="kw">type</span> <span class="dt">ScaleRecipCxt</span> (<span class="ot">r1 ::</span> <span class="fu">*</span>) (<span class="ot">r1&#39; ::</span> <span class="fu">*</span>) r r&#39; rs rs&#39; (<span class="ot">a ::</span> <span class="fu">*</span>) b c <span class="fu">=</span>
(<span class="dt">MultEq</span> a (r1&#39; <span class="ch">&#39;: r&#39;</span>) (r1 <span class="ch">&#39;: r) ,</span>
<span class="dt">MultEq</span> rs rs&#39; <span class="dt">DOne</span>,
b <span class="fu">~</span> <span class="ch">&#39;(r1, r &#39;</span><span class="fu">:</span> rs),
c <span class="fu">~</span> <span class="ch">&#39;(r1&#39;</span>, r&#39; <span class="ch">&#39;: rs&#39;</span>))
<span class="co">-- | a shortcut for @scaleRecip (DScal 1)@</span>
<span class="ot">recipMat ::</span> forall b c e<span class="fu">.</span> (<span class="dt">H.Field</span> e, <span class="dt">ScaleRecip</span> <span class="dt">DOne</span> b c) <span class="ot">=&gt;</span> <span class="dt">D</span> b e <span class="ot">-&gt;</span> <span class="dt">D</span> c e
recipMat m <span class="fu">=</span> scaleRecip (<span class="dt">DScal</span> <span class="dv">1</span><span class="ot"> ::</span> <span class="dt">D</span> <span class="ch">&#39;(DOne, &#39;</span>[]) e) m
<span class="ot">liftH2 ::</span>
( forall h f<span class="fu">.</span> (<span class="dt">H.Container</span> f e, h <span class="fu">~</span> f e) <span class="ot">=&gt;</span> h <span class="ot">-&gt;</span> h <span class="ot">-&gt;</span> h) <span class="ot">-&gt;</span>
<span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> a e
liftH2 f (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (f a b)
liftH2 f (<span class="dt">DVec</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> <span class="dt">DVec</span> (f a b)
add a b <span class="fu">=</span> liftH2 H.add a b
sub a b <span class="fu">=</span> liftH2 H.sub a b
<span class="ot">mulMat ::</span> ( <span class="dt">MultEq</span> as bs cs, <span class="dt">MultEq</span> a b c, cs <span class="fu">~</span> <span class="ch">&#39;[t1 , t2] )</span>
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a,as) e -&gt; D &#39;</span>(b,bs) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(c,cs) e</span>
mulMat (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.mul a b)
<span class="ot">mulVec ::</span> ( <span class="dt">MultEq</span> as bs cs, <span class="dt">MultEq</span> a b c, cs <span class="fu">~</span> <span class="ch">&#39;[t1] )</span>
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a,as) e -&gt; D &#39;</span>(b,bs) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(c,cs) e</span>
mulVec (<span class="dt">DVec</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> <span class="dt">DVec</span> (H.mul a b)
<span class="ot">divideMat ::</span> ( <span class="dt">MultEq</span> as cs bs, <span class="dt">MultEq</span> a c b, cs <span class="fu">~</span> <span class="ch">&#39;[t1 , t2] )</span>
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a,as) e -&gt; D &#39;</span>(b,bs) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(c,cs) e</span>
divideMat (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.divide a b)
<span class="ot">divideVec ::</span> ( <span class="dt">MultEq</span> as cs bs, <span class="dt">MultEq</span> a c b, cs <span class="fu">~</span> <span class="ch">&#39;[t1] )</span>
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a,as) e -&gt; D &#39;</span>(b,bs) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(c,cs) e</span>
divideVec (<span class="dt">DVec</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> <span class="dt">DVec</span> (H.divide a b)
<span class="ot">arctan2 ::</span> (bs <span class="fu">~</span> <span class="dt">MapMapConst</span> <span class="dt">DOne</span> as) <span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a,as) e -&gt; D &#39;</span>(a,as) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(b,bs) e</span>
arctan2 (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.arctan2 a b)
arctan2 (<span class="dt">DVec</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> <span class="dt">DVec</span> (H.arctan2 a b)
<span class="ot">equal ::</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">Bool</span>
equal (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> H.equal a b
equal (<span class="dt">DVec</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> H.equal a b
<span class="co">{- | @cmap f m@ gives a matrix @m&#39;@</span>
<span class="co">@f@ is applied to </span>
<span class="co">-}</span>
<span class="kw">class</span> <span class="dt">CMap</span> f a b e e&#39; <span class="kw">where</span>
<span class="ot"> cmap ::</span> f <span class="ot">-&gt;</span> <span class="dt">D</span> a e <span class="ot">-&gt;</span> <span class="dt">D</span> b e&#39;
<span class="co">-- | Maybe there&#39;s a way to implement in terms of the real cmap (possibly</span>
<span class="co">-- unsafeCoerce?)</span>
<span class="kw">instance</span>
(<span class="dt">ToHLists</span> sh e xs,
<span class="dt">FromHLists</span> xs&#39; sh&#39; e&#39;,
<span class="dt">SameLength</span> xs xs&#39;,
<span class="dt">HMapAux</span> (<span class="dt">HMap</span> f) xs xs&#39;) <span class="ot">=&gt;</span>
<span class="dt">CMap</span> f sh sh&#39; e e&#39; <span class="kw">where</span>
cmap f m <span class="fu">=</span> fromHLists (<span class="dt">HMap</span> f <span class="ot">`hMap`</span> (toHLists<span class="ot"> m ::</span> <span class="dt">HList</span> xs)<span class="ot"> ::</span> <span class="dt">HList</span> xs&#39;)
<span class="kw">type</span> family <span class="dt">AppendEq&#39;</span> (<span class="ot">a ::</span> [k]) (<span class="ot">b ::</span> [k]) (<span class="ot">ab ::</span> [k])<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AppendEq&#39;</span> (a <span class="ch">&#39;: as) b (a&#39;</span> <span class="ch">&#39;: abs) = (a ~ a&#39;</span>, <span class="dt">AppendEq&#39;</span> as b abs)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AppendEq&#39;</span> <span class="ch">&#39;[] b abs = (b ~ abs)</span>
<span class="co">-- | a bit overkill?</span>
<span class="co">-- @a ++ b = ab@</span>
<span class="kw">type</span> <span class="dt">AppendEq</span> a b ab <span class="fu">=</span>
(ab <span class="fu">~</span> <span class="dt">HAppendR</span> a b,
<span class="dt">AppendEq&#39;</span> a b ab,
<span class="dt">SameLength</span> (<span class="dt">DropPrefix</span> a ab) b,
<span class="dt">SameLength</span> (<span class="dt">DropPrefix</span> b ab) a)
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">HAppendR</span> (x <span class="ch">&#39;: xs) ys = x &#39;</span><span class="fu">:</span> <span class="dt">HAppendR</span> xs ys
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">HAppendR</span> <span class="ch">&#39;[] ys = ys</span>
<span class="kw">type</span> family <span class="dt">DropPrefix</span> (<span class="ot">a ::</span> [k]) (<span class="ot">ab ::</span> [k])<span class="ot"> ::</span> [k]
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DropPrefix</span> (a <span class="ch">&#39;: as) (a&#39;</span> <span class="ch">&#39;: abs) = DropPrefix as abs</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">DropPrefix</span> <span class="ch">&#39;[] bs = bs</span>
<span class="co">{- | the slightly involved type here exists because</span>
<span class="co">ci1 and ci2 both start with DOne, but ci2&#39;s contribution</span>
<span class="co">to ci3 does not need a DOne at the start. Another way to</span>
<span class="co">read the constraints here is:</span>
<span class="co">&gt; map (*rem) (a11 : ri) = b11 : bi</span>
<span class="co">&gt; ci3 = ci1 ++ map (*rem) ci2</span>
<span class="co">The same idea happens with vconcat.</span>
<span class="co">-}</span>
hconcat <span class="ot">::</span>
( <span class="dt">MultEq</span> (rem<span class="ot"> ::</span> <span class="fu">*</span>) a b,
<span class="dt">MultEq</span> rem ra rb,
<span class="dt">MultEq</span> rem (<span class="dt">DOne</span> <span class="ch">&#39;: cb) cb&#39;</span>,
<span class="dt">AppendEq</span> ca cb&#39; cc ) <span class="ot">=&gt;</span>
<span class="dt">D</span> <span class="ch">&#39;(a, [ra,ca]) e -&gt; D &#39;</span>(b, [rb, cb]) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, [ra, cc]) e</span>
hconcat (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.fromBlocks [[a, b]])
<span class="ot">vconcat ::</span> (<span class="dt">AppendEq</span> ra (b <span class="ch">&#39;: rb) rc) =&gt;</span>
<span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[ra,ca]) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(b, &#39;</span>[rb,ca]) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[rc,ca]) e
vconcat (<span class="dt">DMat</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.fromBlocks [[a],[b]])
rank, rows,<span class="ot"> cols ::</span> <span class="dt">D</span> t a <span class="ot">-&gt;</span> <span class="dt">Int</span>
rank (<span class="dt">DMat</span> a) <span class="fu">=</span> H.rank a
rows (<span class="dt">DMat</span> a) <span class="fu">=</span> H.rows a
cols (<span class="dt">DMat</span> a) <span class="fu">=</span> H.cols a
<span class="co">-- | H.&#39;H.rows&#39; except type-level</span>
<span class="ot">rowsNT ::</span> <span class="dt">D</span> <span class="ch">&#39;(a, r &#39;</span><span class="fu">:</span> c) e <span class="ot">-&gt;</span> <span class="dt">Proxy</span> (<span class="dt">HLength</span> (a <span class="ch">&#39;: ri))</span>
rowsNT _ <span class="fu">=</span> <span class="dt">Proxy</span>
<span class="co">-- | H.&#39;H.cols&#39; except type-level</span>
<span class="ot">colsNT ::</span> <span class="dt">D</span> <span class="ch">&#39;(a, r &#39;</span><span class="fu">:</span> c <span class="ch">&#39;: cs) e -&gt; Proxy (HLength (DOne &#39;</span><span class="fu">:</span> c))
colsNT _ <span class="fu">=</span> <span class="dt">Proxy</span>
<span class="co">-- | (m `hasRows` n) constrains the matrix/vector @m@ to have @n@ rows</span>
<span class="ot">hasRows ::</span> (<span class="dt">SameLength</span> (<span class="dt">HReplicateR</span> n ()) r, <span class="co">-- forwards</span>
<span class="dt">HLength</span> r <span class="fu">~</span> n <span class="co">-- backwards</span>
) <span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, ra &#39;</span><span class="fu">:</span> ca) e <span class="ot">-&gt;</span> <span class="dt">Proxy</span> (<span class="ot">n ::</span> <span class="dt">HNat</span>) <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, ra &#39;</span><span class="fu">:</span> ca) e
hasRows x _ <span class="fu">=</span> x
<span class="co">-- | (m `hasRows` n) constrains the matrix/vector @m@ to have @n@ rows</span>
<span class="ot">hasCols ::</span> (<span class="dt">SameLength</span> (<span class="dt">HReplicateR</span> n ()) ci, <span class="co">-- forwards</span>
<span class="dt">HLength</span> ci <span class="fu">~</span> n <span class="co">-- backwards</span>
) <span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, ra &#39;</span><span class="fu">:</span> ca <span class="ch">&#39;: rest) e -&gt; Proxy (n :: HNat) -&gt; D &#39;</span>(a, ra <span class="ch">&#39;: ca &#39;</span><span class="fu">:</span> rest) e
hasCols x _ <span class="fu">=</span> x
<span class="co">-- | H.&#39;H.scalar&#39;</span>
<span class="kw">class</span> (<span class="dt">MapConst</span> <span class="ch">&#39;[] as ~ as) =&gt; Scalar as where</span>
<span class="ot"> scalar ::</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, as) e</span>
<span class="kw">instance</span> <span class="dt">Scalar</span> <span class="ch">&#39;[ &#39;</span>[] ] <span class="kw">where</span>
scalar (<span class="dt">DScal</span> a) <span class="fu">=</span> <span class="dt">DVec</span> (H.scalar a)
<span class="kw">instance</span> <span class="dt">Scalar</span> <span class="ch">&#39;[ &#39;</span>[], <span class="ch">&#39;[] ] where</span>
scalar (<span class="dt">DScal</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.scalar a)
<span class="co">{- | Numeric.Container.&#39;H.konst&#39;, but the size is determined by the type.</span>
<span class="co">&gt;&gt;&gt; let n = hSucc (hSucc hZero) -- 2</span>
<span class="co">&gt;&gt;&gt; konst ((1::Double) *~ second) `hasRows` n `hasCols` n</span>
<span class="co">2&gt;&lt;2 1 1 </span>
<span class="co">s 1.0 1.0</span>
<span class="co">s 1.0 1.0</span>
<span class="co">-}</span>
<span class="ot">konst ::</span> forall e a ra ca<span class="fu">.</span>
(<span class="dt">H.Field</span> e,
<span class="dt">HNat2Integral</span> (<span class="dt">HLength</span> (a <span class="ch">&#39;: ra)),</span>
<span class="dt">HNat2Integral</span> (<span class="dt">HLength</span> (<span class="dt">DOne</span> <span class="ch">&#39;: ca)),</span>
<span class="dt">AllEq</span> <span class="dt">DOne</span> ca,
<span class="dt">AllEq</span> a ra)
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[ra, ca]) e
konst (<span class="dt">DScal</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.konst a
(hNat2Integral (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> (<span class="dt">HLength</span> (a <span class="ch">&#39;: ra))),</span>
hNat2Integral (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> (<span class="dt">HLength</span> (<span class="dt">DOne</span> <span class="ch">&#39;: ca)))))</span>
<span class="co">-- | identity matrix. The size is determined by the type.</span>
<span class="ot">ident ::</span> forall ones e<span class="fu">.</span>
(<span class="dt">H.Field</span> e, <span class="dt">HNat2Integral</span> (<span class="dt">HLength</span> (<span class="dt">DOne</span> <span class="ch">&#39;: ones))) =&gt;</span>
<span class="dt">D</span> <span class="ch">&#39;(DOne, [ones, ones]) e</span>
ident <span class="fu">=</span> <span class="dt">DMat</span> (H.ident (hNat2Integral (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> (<span class="dt">HLength</span> (<span class="dt">DOne</span> <span class="ch">&#39;: ones)))))</span>
<span class="co">-- | zero matrix. The size and dimension is determined by the type.</span>
<span class="ot">zeroes ::</span> forall c a r e<span class="fu">.</span> (<span class="dt">H.Field</span> e,
<span class="dt">HNat2Integral</span> (<span class="dt">HLength</span> (a <span class="ch">&#39;: r)),</span>
<span class="dt">HNat2Integral</span> (<span class="dt">HLength</span> (<span class="dt">DOne</span> <span class="ch">&#39;: c)))</span>
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[r, c]) e
zeroes <span class="fu">=</span> <span class="dt">DMat</span> (H.konst <span class="dv">0</span>
(hNat2Integral (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> (<span class="dt">HLength</span> (a <span class="ch">&#39;: r))),</span>
hNat2Integral (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> (<span class="dt">HLength</span> (<span class="dt">DOne</span> <span class="ch">&#39;: c)))))</span>
<span class="kw">type</span> family <span class="dt">CanAddConst</span> (<span class="ot">a ::</span> k) (<span class="ot">m ::</span> [[k]])<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">CanAddConst</span> a [as, ones] <span class="fu">=</span> (<span class="dt">AllEq</span> a as, <span class="dt">AllEq</span> <span class="ch">&#39;[] ones)</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">CanAddConst</span> a <span class="ch">&#39;[as] = (AllEq a as)</span>
<span class="ot">addConstant ::</span> (<span class="dt">H.Field</span> e, <span class="dt">CanAddConst</span> a sh)
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[]) e
<span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, sh) e</span>
<span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, sh) e</span>
addConstant (<span class="dt">DScal</span> a) (<span class="dt">DMat</span> b) <span class="fu">=</span> <span class="dt">DMat</span> (H.addConstant a b)
addConstant (<span class="dt">DScal</span> a) (<span class="dt">DVec</span> b) <span class="fu">=</span> <span class="dt">DVec</span> (H.addConstant a b)
<span class="ot">conj ::</span> <span class="dt">D</span> sh a <span class="ot">-&gt;</span> <span class="dt">D</span> sh a
conj (<span class="dt">DMat</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.conj a)
conj (<span class="dt">DVec</span> a) <span class="fu">=</span> <span class="dt">DVec</span> (H.conj a)
<span class="co">-- | conjugate transpose</span>
ctrans x <span class="fu">=</span> conj <span class="fu">.</span> trans <span class="fu">$</span> x
<span class="ot">diag ::</span> (<span class="dt">MapConst</span> <span class="dt">DOne</span> r <span class="fu">~</span> c, <span class="dt">SameLength</span> r c)
<span class="ot">=&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[r]) t <span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, &#39;</span>[r,c]) t
diag (<span class="dt">DVec</span> a) <span class="fu">=</span> <span class="dt">DMat</span> (H.diag a)
<span class="st">#if MIN_VERSION_hmatrix(0,15,0)</span>
<span class="co">-- | &#39;H.blockDiag&#39;. The blocks should be provided as:</span>
<span class="fu">--</span>
<span class="co">-- @blockDiag $ &#39;hBuild&#39; m1 m2 m3@</span>
<span class="fu">--</span>
<span class="co">-- only available if hmatrix &gt;= 0.15</span>
<span class="ot">diagBlock ::</span> (<span class="dt">HMapOut</span> <span class="dt">UnDimMat</span> (b <span class="ch">&#39;: bs) (H.Matrix e),</span>
<span class="dt">Num</span> e, <span class="dt">H.Field</span> e, <span class="dt">AppendShOf</span> b bs (<span class="dt">D</span> <span class="ch">&#39;(a, sh) e),</span>
sh <span class="fu">~</span> <span class="ch">&#39;[r,c])</span>
<span class="ot">=&gt;</span> <span class="dt">HList</span> (b <span class="ch">&#39;: bs)</span>
<span class="ot">-&gt;</span> <span class="dt">D</span> <span class="ch">&#39;(a, sh) e</span>
diagBlock pairs <span class="fu">=</span> <span class="dt">DMat</span> (H.diagBlock (hMapOut <span class="dt">UnDimMat</span> pairs))
<span class="st">#endif</span>
<span class="kw">data</span> <span class="dt">UnDimMat</span> <span class="fu">=</span> <span class="dt">UnDimMat</span>
<span class="kw">instance</span> (<span class="dt">D</span> sh a <span class="fu">~</span> x, <span class="dt">H.Matrix</span> a <span class="fu">~</span> y) <span class="ot">=&gt;</span> <span class="dt">ApplyAB</span> <span class="dt">UnDimMat</span> x y <span class="kw">where</span>
applyAB _ (<span class="dt">DMat</span> x) <span class="fu">=</span> x
<span class="kw">class</span> <span class="dt">DiagBlock</span> (<span class="ot">bs ::</span> [<span class="fu">*</span>]) t
<span class="co">-- | @AppendShOf a [b,c,d] aas@ makes aas have the type of a matrix that</span>
<span class="co">-- has a,b,c,d along the diagonal</span>
<span class="kw">class</span> <span class="dt">AppendShOf</span> a (<span class="ot">as ::</span> [<span class="fu">*</span>]) aas
<span class="kw">instance</span>
(e <span class="fu">~</span> f, f <span class="fu">~</span> g,
<span class="dt">AppendShOf</span> (<span class="dt">D</span> ab e) ds z,
<span class="dt">AppendDims</span> a b ab,
<span class="co">-- constraints to force D in the type</span>
x <span class="fu">~</span> <span class="dt">D</span> a e,
y <span class="fu">~</span> <span class="dt">D</span> b f,
z <span class="fu">~</span> <span class="dt">D</span> c g) <span class="ot">=&gt;</span>
<span class="dt">AppendShOf</span> x (y <span class="ch">&#39;: ds) z </span>
<span class="kw">instance</span> (x <span class="fu">~</span> z) <span class="ot">=&gt;</span> <span class="dt">AppendShOf</span> x <span class="ch">&#39;[] z</span>
<span class="kw">type</span> family <span class="dt">AppendDims</span> (<span class="ot">a ::</span> (<span class="fu">*</span>, [[<span class="fu">*</span>]])) (<span class="ot">b ::</span> (<span class="fu">*</span>, [[<span class="fu">*</span>]])) (<span class="ot">c ::</span> (<span class="fu">*</span>, [[<span class="fu">*</span>]]))<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">AppendDims</span> <span class="ch">&#39;(a, [ra,ca]) &#39;</span>(b, [rb,cb]) <span class="ch">&#39;(c, [rc,cc])</span>
<span class="fu">=</span> (c <span class="fu">~</span> a, <span class="dt">AppendEq</span> ra (b <span class="ch">&#39;: rb) rc, AppendEq ca cb cc)</span>
<span class="co">-- how to handle vectors?</span>
<span class="co">--type instance AppendDims &#39;(a, &#39;[ra]) &#39;(b, &#39;[rb]) = &#39;(a, &#39;[HAppendR ra (b &#39;: rb)])</span>
<span class="kw">class</span> <span class="dt">ToHList</span> sh e result <span class="kw">where</span>
<span class="ot"> toHList ::</span> <span class="dt">D</span> sh e <span class="ot">-&gt;</span> <span class="dt">HList</span> result
<span class="co">-- | given a vector like @x = DimMat &#39;[units] e@ this does something like</span>
<span class="co">-- @[ (x \@&gt; i) | i &lt;- [1 .. n] ]@, if we had comprehensions for HLists</span>
<span class="kw">instance</span>
(<span class="dt">HListFromList</span> e e1,
<span class="dt">SameLength</span> result e1,
<span class="dt">HMapAux</span> <span class="dt">AddDimensional</span> e1 result,
<span class="dt">ToHListRow</span> (r <span class="ch">&#39;: rs) e result) =&gt;</span>
<span class="dt">ToHList</span> <span class="ch">&#39;(r, &#39;</span>[rs]) e result <span class="kw">where</span>
toHList (<span class="dt">DVec</span> v) <span class="fu">=</span> <span class="kw">case</span> hListFromList (H.toList v)<span class="ot"> ::</span> <span class="dt">HList</span> e1 <span class="kw">of</span>
e1 <span class="ot">-&gt;</span> hMap <span class="dt">AddDimensional</span> e1
<span class="kw">class</span> <span class="dt">HListFromList</span> e e&#39; <span class="kw">where</span>
<span class="ot"> hListFromList ::</span> [e] <span class="ot">-&gt;</span> <span class="dt">HList</span> e&#39;
<span class="kw">instance</span> <span class="dt">HListFromList</span> e <span class="ch">&#39;[] where</span>
hListFromList _ <span class="fu">=</span> <span class="dt">HNil</span>
<span class="kw">instance</span> (e <span class="fu">~</span> e&#39;, <span class="dt">HListFromList</span> e es) <span class="ot">=&gt;</span> <span class="dt">HListFromList</span> e (e&#39; <span class="ch">&#39;: es) where</span>
hListFromList (e <span class="fu">:</span> es) <span class="fu">=</span> e <span class="ot">`HCons`</span> hListFromList es
<span class="kw">type</span> family <span class="dt">ToHListRow</span> (<span class="ot">a ::</span> [<span class="fu">*</span>]) e (<span class="ot">b ::</span> [<span class="fu">*</span>])<span class="ot"> ::</span> <span class="dt">Constraint</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">ToHListRow</span> (a <span class="ch">&#39;: as) e (b &#39;</span><span class="fu">:</span> bs) <span class="fu">=</span> (<span class="dt">Quantity</span> a e <span class="fu">~</span> b, <span class="dt">ToHListRow</span> as e bs)
<span class="kw">data</span> <span class="dt">AddDimensional</span> <span class="fu">=</span> <span class="dt">AddDimensional</span>
<span class="kw">instance</span> (<span class="dt">Quantity</span> t x <span class="fu">~</span> y) <span class="ot">=&gt;</span> <span class="dt">ApplyAB</span> <span class="dt">AddDimensional</span> x y <span class="kw">where</span>
applyAB _ x <span class="fu">=</span> <span class="dt">Dimensional</span> x
<span class="kw">class</span> <span class="dt">FromHList</span> list sh e <span class="kw">where</span>
<span class="ot"> fromHList ::</span> <span class="dt">HList</span> list <span class="ot">-&gt;</span> <span class="dt">D</span> sh e
<span class="kw">instance</span>
(<span class="dt">H.Field</span> e,
<span class="dt">HMapOut</span> <span class="dt">RmDimensional</span> list e,
<span class="dt">ToHListRow</span> (r <span class="ch">&#39;: rs) e list) =&gt;</span>
<span class="dt">FromHList</span> list <span class="ch">&#39;(r, &#39;</span>[rs]) e <span class="kw">where</span>
fromHList xs <span class="fu">=</span> <span class="dt">DVec</span> (H.fromList (hMapOut <span class="dt">RmDimensional</span> xs))
<span class="kw">data</span> <span class="dt">RmDimensional</span> <span class="fu">=</span> <span class="dt">RmDimensional</span>
<span class="kw">instance</span> (x <span class="fu">~</span> <span class="dt">Quantity</span> d y) <span class="ot">=&gt;</span> <span class="dt">ApplyAB</span> <span class="dt">RmDimensional</span> x y <span class="kw">where</span>
applyAB _ (<span class="dt">Dimensional</span> a) <span class="fu">=</span> a
<span class="kw">class</span> <span class="dt">FromHLists</span> lists sh e <span class="kw">where</span>
<span class="ot"> fromHLists ::</span> <span class="dt">HList</span> lists <span class="ot">-&gt;</span> <span class="dt">D</span> sh e
<span class="co">-- | [[Dim e unit]] -&gt; DimMat units e</span>
<span class="kw">instance</span>
(<span class="dt">ToHListRows&#39;</span> (r1 <span class="ch">&#39;: r) c e lists,</span>
<span class="dt">HMapOut</span> (<span class="dt">HMapOutWith</span> <span class="dt">RmDimensional</span>) lists [e],
<span class="dt">H.Field</span> e) <span class="ot">=&gt;</span>
<span class="dt">FromHLists</span> lists <span class="ch">&#39;(r1, [r,c]) e where</span>
fromHLists xs <span class="fu">=</span> <span class="dt">DMat</span> (H.fromLists (hMapOut (<span class="dt">HMapOutWith</span> <span class="dt">RmDimensional</span>) xs))
<span class="kw">newtype</span> <span class="dt">HMapOutWith</span> f <span class="fu">=</span> <span class="dt">HMapOutWith</span> f
<span class="kw">instance</span> (<span class="dt">HMapOut</span> f l e, es <span class="fu">~</span> [e], <span class="dt">HList</span> l <span class="fu">~</span> hl) <span class="ot">=&gt;</span> <span class="dt">ApplyAB</span> (<span class="dt">HMapOutWith</span> f) hl es <span class="kw">where</span>
applyAB (<span class="dt">HMapOutWith</span> f) <span class="fu">=</span> hMapOut f
<span class="kw">class</span> <span class="dt">ToHListRows&#39;</span> (<span class="ot">r ::</span> [<span class="fu">*</span>]) (<span class="ot">c ::</span> [<span class="fu">*</span>]) (<span class="ot">e ::</span> <span class="fu">*</span>) (<span class="ot">rows ::</span> [<span class="fu">*</span>])
<span class="kw">instance</span> <span class="dt">ToHListRows&#39;</span> <span class="ch">&#39;[] c e &#39;</span>[]
<span class="kw">instance</span> (<span class="dt">ToHListRows&#39;</span> r c e rows,
<span class="dt">MultEq</span> r c c&#39;,
<span class="dt">HMapCxt</span> (<span class="dt">AddQty</span> e) (<span class="dt">HList</span> c&#39;) hListRow c&#39; row&#39;)
<span class="ot">=&gt;</span> <span class="dt">ToHListRows&#39;</span> (r1 <span class="ch">&#39;: r) c e (hListRow &#39;</span><span class="fu">:</span> rows)
<span class="kw">data</span> <span class="dt">AddQty</span> u
<span class="kw">instance</span> (qty <span class="fu">~</span> <span class="dt">Quantity</span> u e) <span class="ot">=&gt;</span> <span class="dt">ApplyAB</span> (<span class="dt">AddQty</span> u) e qty
<span class="kw">class</span> <span class="dt">ToHLists</span> sh e xs <span class="kw">where</span>
<span class="ot"> toHLists ::</span> <span class="dt">D</span> sh e <span class="ot">-&gt;</span> <span class="dt">HList</span> xs
<span class="co">-- | DimMat units e -&gt; [[Dim e unit]]</span>
<span class="kw">instance</span>
(<span class="dt">HListFromList</span> e e1,
<span class="dt">HListFromList</span> (<span class="dt">HList</span> e1) e2,
<span class="dt">HMapAux</span> (<span class="dt">HMap</span> <span class="dt">AddDimensional</span>) e2 xs,
<span class="dt">ToHListRows&#39;</span> ri ci e xs,
<span class="dt">SameLength</span> e2 xs,
(r1 <span class="ch">&#39;: r) ~ ri, (DOne &#39;</span><span class="fu">:</span> c) <span class="fu">~</span> ci )
<span class="ot">=&gt;</span> <span class="dt">ToHLists</span> <span class="ch">&#39;(r1, [r,c]) e xs where</span>
toHLists (<span class="dt">DMat</span> m) <span class="fu">=</span> <span class="kw">case</span> hListFromList (map hListFromList (H.toLists m)<span class="ot"> ::</span> [<span class="dt">HList</span> e1])<span class="ot"> ::</span> <span class="dt">HList</span> e2 <span class="kw">of</span>
e2 <span class="ot">-&gt;</span> hMap (<span class="dt">HMap</span> <span class="dt">AddDimensional</span>) e2
<span class="co">{- still bad</span>
<span class="co">class PairsToList a t where</span>
<span class="co"> pairsToList :: a -&gt; [H.Matrix t]</span>
<span class="co">instance PairsToList () t where</span>
<span class="co"> pairsToList _ = []</span>
<span class="co">instance (PairsToList b t, t&#39; ~ t) =&gt; PairsToList (DimMat sh t&#39;,b) t where</span>
<span class="co"> pairsToList (DimMat a,b) = a : pairsToList b</span>
<span class="co">class EigV (sh :: [[ [DimSpec *] ]])</span>
<span class="co"> (eigenValue :: [[DimSpec *]])</span>
<span class="co"> (eigenVector :: [[[DimSpec *]]])</span>
<span class="co">instance</span>
<span class="co"> ( SameLengths [r,c,r&#39;,c&#39;,rinv,cinv,eigval,erinv],</span>
<span class="co"> -- ZipWithMul r c eigval,</span>
<span class="co"> MapConst &#39;[] r ~ eigval,</span>
<span class="co"> PInv [r&#39;,c&#39;] [rinv,cinv],</span>
<span class="co"> -- AreRecips r&#39; cinv,</span>
<span class="co"> -- AreRecips c&#39; rinv,</span>
<span class="co"> cinv ~ c,</span>
<span class="co"> c ~ (&#39;[] &#39;: _1),</span>
<span class="co"> c&#39; ~ (&#39;[] &#39;: _2),</span>
<span class="co"> ZipWithMul eigval rinv erinv,</span>
<span class="co"> MultiplyCxt [r&#39;,c&#39;] erinv r,</span>
<span class="co"> sh ~ [r,c],</span>
<span class="co"> sh&#39; ~ [r&#39;,c&#39;])</span>
<span class="co"> =&gt; EigV sh eigval sh&#39;</span>
<span class="co">-- | when no eigenvectors are needed</span>
<span class="co">type family EigE (sh :: [[ [DimSpec *] ]]) (eigenValue :: [ [DimSpec *] ]) :: Constraint</span>
<span class="co">type instance EigE [r,c] eigval = ( SameLengths [r,c,eigval], ZipWithMul r c eigval)</span>
<span class="co">{- $eigs</span>
<span class="co">The Hmatrix eig factors A into P and D where A = P D inv(P) and D is diagonal.</span>
<span class="co">The units for eigenvalues can be figured out:</span>
<span class="co">&gt; _____</span>
<span class="co">&gt; -1 | c</span>
<span class="co">&gt; P D P = A = |r</span>
<span class="co">&gt; |</span>
<span class="co">&gt; _______</span>
<span class="co">&gt; | d</span>
<span class="co">&gt; P = |c</span>
<span class="co">&gt; |</span>
<span class="co">&gt; _______</span>
<span class="co">&gt; | -1</span>
<span class="co">&gt; | c</span>
<span class="co">&gt; -1 | </span>
<span class="co">&gt; P = | -1</span>
<span class="co">&gt; |d</span>
<span class="co">So we can see that the dimension labeled `d-1` in P inverse is actually the</span>
<span class="co">same `c` in `A`. The actual units of `d` don&#39;t seem to matter because the</span>
<span class="co">`inv(d)` un-does any units that the `d` adds. So `d` can be all DOne. But</span>
<span class="co">another choice, such as 1/c would be more appropriate, since then you can</span>
<span class="co">expm your eigenvectors (not that that seems to be something people do)?</span>
<span class="co">To get the row-units of A to match up, sometimes `D` will have units. </span>
<span class="co">The equation ends up as D/c = r</span>
<span class="co">Please ignore the type signatures on &#39;eig&#39; &#39;eigC&#39; etc. instead look at the type of</span>
<span class="co">&#39;wrapEig&#39; &#39;wrapEigOnly&#39; together with the hmatrix documentation (linked).</span>
<span class="co">Perhaps the convenience definitions `eig m = wrapEig H.eig m` should be in</span>
<span class="co">another module.</span>
<span class="co">-}</span>
<span class="co">{-</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eig&#39;</span>
<span class="co">eig m = wrapEig H.eig m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigC&#39;</span>
<span class="co">eigC m = wrapEig H.eigC m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigH&#39;</span>
<span class="co">eigH m = wrapEig H.eigH m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigH&#39;&#39;</span>
<span class="co">eigH&#39; m = wrapEig H.eigH&#39; m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigR&#39;</span>
<span class="co">eigR m = wrapEig H.eigR m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigS&#39;</span>
<span class="co">eigS m = wrapEig H.eigS m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigS&#39;&#39;</span>
<span class="co">eigS&#39; m = wrapEig H.eigS&#39; m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigSH&#39;</span>
<span class="co">eigSH m = wrapEig H.eigSH m</span>
<span class="co">-- | &#39;wrapEig&#39; H.&#39;H.eigSH&#39;&#39;</span>
<span class="co">eigSH&#39; m = wrapEig H.eigSH&#39; m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigOnlyC&#39;</span>
<span class="co">eigOnlyC m = wrapEigOnly H.eigOnlyC m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigOnlyH&#39;</span>
<span class="co">eigOnlyH m = wrapEigOnly H.eigOnlyH m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigOnlyR&#39;</span>
<span class="co">eigOnlyR m = wrapEigOnly H.eigOnlyR m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigOnlyS&#39;</span>
<span class="co">eigOnlyS m = wrapEigOnly H.eigOnlyS m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigenvalues&#39;</span>
<span class="co">eigenvalues m = wrapEigOnly H.eigenvalues m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigenvaluesSH&#39;</span>
<span class="co">eigenvaluesSH m = wrapEigOnly H.eigenvaluesSH m</span>
<span class="co">-- | &#39;wrapEigOnly&#39; H.&#39;H.eigenvaluesSH&#39;&#39;</span>
<span class="co">eigenvaluesSH&#39; m = wrapEigOnly H.eigenvaluesSH&#39; m</span>
<span class="co">-}</span>
<span class="ot">wrapEig ::</span> (c&#39; <span class="fu">~</span> (<span class="ch">&#39;[] &#39;</span><span class="fu">:</span> _1),
<span class="dt">EigV</span> [r,c] eigVal [r&#39;,c&#39;],
<span class="dt">H.Field</span> y, <span class="dt">H.Field</span> z)
<span class="ot">=&gt;</span> (<span class="dt">H.Matrix</span> x <span class="ot">-&gt;</span> (<span class="dt">H.Vector</span> y, <span class="dt">H.Matrix</span> z)) <span class="ot">-&gt;</span>
<span class="dt">DimMat</span> [r,c] x <span class="ot">-&gt;</span>
(<span class="dt">DimMat</span> <span class="ch">&#39;[eigVal] y, DimMat [r&#39;</span>,c&#39;] z)
wrapEig hmatrixFun (<span class="dt">DimMat</span> a) <span class="fu">=</span> <span class="kw">case</span> hmatrixFun a <span class="kw">of</span>
(e,v) <span class="ot">-&gt;</span> (<span class="dt">DimVec</span> e, <span class="dt">DimMat</span> v)
<span class="ot">wrapEigOnly ::</span> (<span class="dt">EigE</span> [r,c] eigVal, <span class="dt">H.Field</span> y)
<span class="ot">=&gt;</span> (<span class="dt">H.Matrix</span> x <span class="ot">-&gt;</span> <span class="dt">H.Vector</span> y) <span class="ot">-&gt;</span>
<span class="dt">DimMat</span> [r,c] x <span class="ot">-&gt;</span> <span class="dt">DimMat</span> <span class="ch">&#39;[eigVal] y</span>
wrapEigOnly hmatrixFun (<span class="dt">DimMat</span> a) <span class="fu">=</span> <span class="kw">case</span> hmatrixFun a <span class="kw">of</span>
(e) <span class="ot">-&gt;</span> <span class="dt">DimVec</span> e
<span class="fu">-</span>}
<span class="co">-- | @\\a xs -&gt; map (map (const a)) xs@</span>
<span class="kw">type</span> family <span class="dt">MapMapConst</span> (<span class="ot">a::</span>k) (<span class="ot">xs ::</span> [[l]])<span class="ot"> ::</span> [[k]]
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">MapMapConst</span> a (x <span class="ch">&#39;: xs) = MapConst a x &#39;</span><span class="fu">:</span> <span class="dt">MapMapConst</span> a xs
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">MapMapConst</span> a <span class="ch">&#39;[] = &#39;</span>[]
<span class="co">-- | @\\a xs -&gt; map (const a) xs@</span>
<span class="kw">type</span> family <span class="dt">MapConst</span> (<span class="ot">a ::</span> k) (<span class="ot">xs ::</span> [l])<span class="ot"> ::</span> [k]
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">MapConst</span> a (x <span class="ch">&#39;: xs) = a &#39;</span><span class="fu">:</span> <span class="dt">MapConst</span> a xs
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">MapConst</span> a <span class="ch">&#39;[] = &#39;</span>[]
<span class="co">-- | convert from (a,(b,(c,(d,())))) to &#39;[a,b,c,d]</span>
<span class="kw">type</span> family <span class="dt">FromPairs</span> (<span class="ot">a ::</span> <span class="fu">*</span>)<span class="ot"> ::</span> [<span class="fu">*</span>]
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">FromPairs</span> (a,b) <span class="fu">=</span> a <span class="ch">&#39;: FromPairs b</span>
<span class="kw">type</span> <span class="kw">instance</span> <span class="dt">FromPairs</span> () <span class="fu">=</span> <span class="ch">&#39;[]</span>
<span class="co">{-</span>
<span class="co">-- | @map fst@</span>
<span class="co">type family MapFst (a :: *) :: [*]</span>
<span class="co">type instance MapFst ((a,_t) , as) = a &#39;: MapFst as</span>
<span class="co">type instance MapFst () = &#39;[]</span>
<span class="co">-- | @\\a xs -&gt; map (/a) xs@</span>
<span class="co">type family MapDiv (a :: k) (xs :: [k]) :: [k]</span>
<span class="co">type instance MapDiv a (x &#39;: xs) = (x @- a) &#39;: MapDiv a xs</span>
<span class="co">type instance MapDiv a &#39;[] = &#39;[]</span>
<span class="co">type family UnDQuantity (a :: [*]) :: [ [*] ]</span>
<span class="co">type instance UnDQuantity (x &#39;: xs) = UnDQuantity1 x &#39;: UnDQuantity xs</span>
<span class="co">type instance UnDQuantity &#39;[] = &#39;[]</span>
<span class="co">type family UnDQuantity1 (a :: *) :: [*] </span>
<span class="co">type instance UnDQuantity1 (Unit t x) = x</span>
<span class="co">type family DimMatFromTuple ijs :: * -&gt; *</span>
<span class="co">type instance DimMatFromTuple ijs =</span>
<span class="co"> DimMat [UnDQuantity (MapFst ijs),</span>
<span class="co"> &#39;[] &#39;: MapDiv (UnDQuantity1 (Fst (Fst ijs)))</span>
<span class="co"> (UnDQuantity (FromPairs (Snd (Fst ijs))))]</span>
<span class="co">type family Append (a :: [k]) (b :: [k]) :: [k]</span>
<span class="co">type instance Append (a &#39;: as) b = a &#39;: Append as b</span>
<span class="co">type instance Append &#39;[] b = b</span>
<span class="co">-}</span></code></pre>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment