Reißverschluss-Comonaden, generisch

Bei jedem Containertyp können wir den (elementorientierten) Reißverschluss bilden und wissen, dass diese Struktur eine Comonade ist. Dies wurde vor kurzem in wunderbarem Detail untersuchteine weitere Frage zum Stapelüberlauf für folgenden Typ:

data Bin a = Branch (Bin a) a (Bin a) | Leaf a deriving Functor

mit folgendem reißverschluss

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 ...

Es ist der Fall, dassZip ist einComonad obwohl die Konstruktion seiner Instanz ein wenig haarig ist. Das gesagt,Zip vollständig mechanisch abgeleitet werden kannTree und (ich glaube) jeder auf diese Weise abgeleitete Typ ist automatisch einComonadDaher sollte es meiner Meinung nach so sein, dass wir diese Typen und ihre Comonaden generisch und automatisch konstruieren können.

Ein Verfahren zum Erreichen der Allgemeinheit für die Reißverschlusskonstruktion ist die Verwendung der folgenden Klassen- und Typenfamilie

data Zipper t a = Zipper { diff :: D t a, here :: a }

deriving instance Diff t => Functor (Zipper t)

class (Functor t, Functor (D t)) => Diff t where
  data D t :: * -> *
  inTo  :: t a -> t (Zipper t a)
  outOf :: Zipper t a -> t a

Das ist (mehr oder weniger) in den Haskell Cafe-Threads und auf Conal Elliotts Blog aufgetaucht. Diese Klasse kann für die verschiedenen algebraischen Kerntypen instanziiert werden und bietet somit einen allgemeinen Rahmen, um über die Ableitungen von ADTs zu sprechen.

Meine Frage ist also letztendlich, ob wir schreiben können oder nicht

instance Diff t => Comonad (Zipper t) where ...

die verwendet werden könnten, um die oben beschriebene spezifische Comonad-Instanz zu subsumieren:

instance Diff Bin where
  data D Bin a = DBin { context :: [Step a], descend :: Maybe (Bin a, Bin a) }
  ...

Leider hatte ich kein Glück, eine solche Instanz zu schreiben. Ist der,inTo/outOf Unterschrift ausreichend? Wird noch etwas benötigt, um die Typen einzuschränken? Ist diese Instanz überhaupt möglich?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage