title: Zipper Comonads, Generically
body: <p>Given any container type we can form the (element-focused) Zipper and know that this structure is a Comonad. This was recently explored in wonderful detail in <a href="https://stackoverflow.com/questions/25519767/how-to-make-a-binary-tree-zipper-an-instance-of-comonad">another Stack Overflow question</a> for the following type:</p>
  
  <pre><code>data Bin a = Branch (Bin a) a (Bin a) | Leaf a deriving Functor
  </code></pre>
  
  <p>with the following zipper</p>
  
  <pre><code>data Dir = L | R
  data Step a = Step a Dir (Bin a)   deriving Functor
  data Zip  a = Zip [Step a] (Bin a) deriving Functor
  instance Comonad Zip where ...
  </code></pre>
  
  <p>It is the case that <code>Zip</code> is a <code>Comonad</code> though the construction of its instance is a little hairy. That said, <code>Zip</code> can be completely mechanically derived from <code>Tree</code> and (I believe) any type derived this way is automatically a <code>Comonad</code>, so I feel it ought to be the case that we can construct these types and their comonads generically and automatically.</p>
  
  <p>One method for achieving generality for zipper construction is the use the following class and type family</p>
  
  <pre><code>data Zipper t a = Zipper { diff :: D t a, here :: a }
  
  deriving instance Diff t =&gt; Functor (Zipper t)
  
  class (Functor t, Functor (D t)) =&gt; Diff t where
    data D t :: * -&gt; *
    inTo  :: t a -&gt; t (Zipper t a)
    outOf :: Zipper t a -&gt; t a
  </code></pre>
  
  <p>which has (more or less) shown up in Haskell Cafe threads and on Conal Elliott's blog. This class can be instantiated for the various core algebraic types and thus provides a general framework for talking about the derivatives of ADTs.</p>
  
  <p>So, ultimately, my question is whether or not we can write</p>
  
  <pre><code>instance Diff t =&gt; Comonad (Zipper t) where ...
  </code></pre>
  
  <p>which could be used to subsume the specific Comonad instance described above:</p>
  
  <pre><code>instance Diff Bin where
    data D Bin a = DBin { context :: [Step a], descend :: Maybe (Bin a, Bin a) }
    ...
  </code></pre>
  
  <p>Unfortunately, I've had no luck writing such an instance. Is the <code>inTo</code>/<code>outOf</code> signature sufficient? Is there something else needed to constrain the types? Is this instance even possible?</p>