title: Simplfying kind by fixating parameter
body: <p>This is a follow-up to <a href="https://stackoverflow.com/questions/41981611/bind-type-parameter" title="this question">this question</a>, but the problem is slightly different in application and reason so I chose to ask a new question.</p>
  
  <p>Consider these definitions (<em>edit: These are part of an external library</em>):</p>
  
  <pre><code>class (Num a, Cast a b, Cast b a, Storable b, Code b) =&gt; Elem a b | a -&gt; b where
  
  data Matrix a b where
      Matrix :: Elem a b =&gt; !Int -&gt; !Int -&gt; !(Vector b) -&gt; Matrix a b
  
  instance Elem Float CFloat where
  instance Elem Double CDouble where
  instance Elem (Complex Float) (CComplex CFloat) where
  instance Elem (Complex Double) (CComplex CDouble) where
  </code></pre>
  
  <p>In other words a floating point matrix with underlying C type "fixed" by the functional dependency Elem.</p>
  
  <p>Now in order to implement some instances for certain container specific classes (in my specific case for the <a href="https://hackage.haskell.org/package/keys-3.11/docs/Data-Key.html#t:Lookup" rel="nofollow noreferrer" title="Lookup">Lookup</a> class, but Ixed from lens might be another candidate) I need a Matrix type with one type parameter.</p>
  
  <p>I tried the following:</p>
  
  <pre><code>type family CType a where
      CType Double = CDouble
      CType Float = CFloat
      CType (Complex Double) = (CComplex CDouble)
      CType (Complex Float) = (CComplex CFloat)
  
   newtype MatX a = MatX { getMatX :: Matrix a (CType a) }
  </code></pre>
  
  <p>Note that I am not allowed to simply omit the "b" type in the newtype declaration so the type synonym serves as a means to fix the internal type.</p>
  
  <p>However, all functions on the Matrix type have types like</p>
  
  <pre><code>(Elem a b) =&gt; Matrix a b -&gt; some -&gt; other -&gt; params -&gt; result
  </code></pre>
  
  <p>As an example the unsafeCoeff function looks like this:</p>
  
  <pre><code>unsafeCoeff :: Elem a b =&gt; Int -&gt; Int -&gt; Matrix a b -&gt; a
  unsafeCoeff row col (Matrix rows _ vals) = cast $ Data.Vector.Storable.unsafeIndex vals $ col * rows + row
  </code></pre>
  
  <p>using this type MatX like for example:</p>
  
  <pre><code>instance Lookup MatX where
      lookup (i,j) m = Just $ unsafeCoeff i j (getMatX m)
  </code></pre>
  
  <p>gives me the error "No instance for (Elem a (CType a))". Since I am not allowed to specify these instances (since type synonyms are not allowed in instance declarations) I am kind of stuck at this point. I see why the compiler cannot assume that Elem a (CType a) is indeed given, but I don't know how to specify this relation.</p>
  
  <p>Bonus:</p>
  
  <p>I also tried to just do this:</p>
  
  <pre><code>instance Lookup (Matrix a) where
      lookup (i,j) m = Just $ unsafeCoeff i j m :: Maybe a
  </code></pre>
  
  <p>But then "b" is the element type of the container and the lookup function must return (the unspecified) b.</p>
  
  <p>Edit: For completeness sake the definition of Lookup from the link above:</p>
  
  <pre><code>type family Key f 
  
  class Lookup f where
      lookup :: Key f -&gt; f a -&gt; Maybe a 
  </code></pre>