2014-06-06 9 views
14

Ich bin in der Notwendigkeit der folgenden Klasse von Funktionen:Ist das Konzept eines "interleaved homomorphism" eine echte Sache?

class InterleavedHomomorphic x where 
    interleaveHomomorphism :: (forall a . f a -> g a) -> x f -> x g 

Offensichtlich ist der Name, den ich für sie erfunden ist in keiner Weise eine offizielle Bezeichnung für etwas, und die Typklasse oben ist nicht sehr elegant. Ist das ein Konzept, das in einer Bibliothek einen Namen oder gar eine Implementierung hat? Gibt es einen vernünftigeren Weg dies zu tun?


Der Zweck dieser Funktion wäre, dass ich einig Kontext f habe, die einige Daten (Foo und Bar sind nur willkürliche Beispiel Datenstrukturen für die Zwecke dieser Frage) annotiert: I

data Foo f = One (f (Bar f)) | Product (f (Foo f)) (f (Foo f)) 
data Bar f = Zero | Succ (f (Bar f)) 

möchte den Kontext der Daten auf eine polymorphe Weise transformieren; indem man nur den Homomorphismus zwischen den Kontexten kennt und sich nicht (notwendigerweise) um die Daten selbst kümmert. Dies würde durch Bereitstellen von instance InterleavedHomomorphic Foo und instance InterleavedHomomorphic Bar im obigen Beispiel erfolgen.

Antwort

17

Also unter der Annahme f und g sind richtige Funktoren, forall a. f a -> g a ist eine natürliche Transformation. Wir konnten machen es ein bisschen schöner:

type f ~> g = forall a. f a -> g a 

Natürliche Transformationen wie diese lassen Sie uns eine Kategorie von Haskell Funktoren bilden, also was Sie haben, ist ein Funktor aus, dass bis zu einem gewissen anderen Kategorie.

Befolgen Sie die Schritte normaler Haskell Functors, es wäre vielleicht sinnvoll, x einen Endofunctor zu haben, der Funktoren anderen Funktoren zuordnet. Dies ist ähnlich, aber nicht identisch, zu dem, was Sie haben:

class FFunctor x where 
    ffmap :: (f ~> g) -> (x f ~> x g) 

aber in Ihrem Fall x f und x g sind nicht functors und x f -> x g ist eine normale Funktion eher als eine natürliche Transformation. Dennoch ist das Muster nah genug, um faszinierend zu sein.

In diesem Sinne scheint es, dass x immer noch ein Beispiel für einen Funktor ist, nur zwischen zwei verschiedenen Kategorien. Es geht von der Kategorie Funktoren in die Kategorie x mit unterschiedlichen Strukturen. Jede mögliche x, wie Foo, bildet eine Kategorie mit Objekten wie Foo [] und Foo Maybe und Transformationen zwischen ihnen (Foo [] -> Foo Maybe). Ihre interleaveHomomorphism Funktion "hebt" natürliche Transformationen in diese x-morphisms, genau wie fmap "hebt" normal (a -> b) Funktionen in Funktionen in das Bild des Funktors (f a -> f b).

Also ja: Ihre Typklasse ist ein Funktor wie Functor, außer zwischen zwei verschiedenen Kategorien. Ich kenne keinen spezifischen Namen dafür, hauptsächlich weil ich keinen spezifischen Namen für Konstrukte wie x kenne.

Ganz allgemein bin ich nicht einmal sicher, dass ein bestimmter Name sinnvoll wäre. An dieser Stelle würden wir wahrscheinlich eine nette generische Funktorklasse mögen, die zwischen zwei Kategorien geht.Vielleicht etwas wie:

class (Category catA, Category catB) => GFunctor f catA catB where 
    gfmap :: catA a b -> catB (f a) (f b) 

Dies ist wahrscheinlich bereits in einer Bibliothek irgendwo vorhanden.

Leider erfordert dieser spezielle Ansatz zum Definieren verschiedener Funktoren eine Menge zusätzlichen Rauschens, da (->) bereits eine Kategorie ist. In der Tat wird es ein bisschen schwierig sein, alle Typen richtig auszurichten.

So ist es wahrscheinlich am einfachsten, es einfach eine XFunctor oder so etwas zu nennen. Stellen Sie sich die pun potential vor!

EDIT: Es sieht aus wie categories eine CFunctor Art wie diese bietet, aber ein bisschen schlauer:

class (Category r, Category s) => CFunctor f r s | f r -> s, f s -> r where 
    cmap :: r a b -> s (f a) (f b) 

Allerdings bin ich mir nicht sicher, dass auch dies allgemein genug ist! Ich denke, dass wir vielleicht wollen, dass es polymorpher über Arten auch ist.

+3

Sicher genug existiert etwas wie 'GFunctor'; in der Tat würden Mathematiker endofunctors, wie diejenigen, die wir in ** Hask ** haben, als einen besonderen Fall betrachten und gewöhnlich mit Funktoren zwischen verschiedenen Kategorien umgehen. Edward parametrisiert ['class (Kategorie r, Kategorie t) => Functor f r t | fr -> t, ft -> r'] (http://hackage.haskell.org/package/categories-1.0.6/docs/Control-Categorical-Functor.html) 'wo fmap :: rab -> t (fa) (fb) '. – leftaroundabout

+0

@leftaroundabout: Danke! Ich habe die alte Version in 'category-extras' gefunden, aber es sieht so aus als ob' categories' das neuere, bessere Paket ist. –

+0

Ich sehe nicht, wie 'f' und' g' funktors sein müssen. Es ist jedoch sinnvoll, 'x' als Funktor aus einer Kategorie generischer existentiell quantifizierter Morphismen in eine andere Kategorie zu behandeln. Es ist gut zu sehen, dass "CFunctor" existiert, aber es ist schade, dass es kein sehr rigoroses und umfassendes Framework dafür gibt, um nützlich zu sein. Ich denke, ich werde mich sowieso auf meinen Anwendungsfall spezialisieren müssen. Aber diese Antwort macht Sinn, also werde ich es akzeptieren! – dflemstr

0

Bar f sieht aus wie die Free MonadFree f().

Dann Foo ist ein do mit einem oder zwei <-. Vielleicht von dort aus weiter ...

+0

Wie ich in der Frage gesagt habe, habe ich nur die Datentypen 'Foo' und' Bar' erfunden. In Wirklichkeit habe ich es mit sehr unterschiedlichen Datenstrukturen zu tun. – dflemstr

0

Für was es wert ist, können Sie eine vereinfachte Version von Ihrem Beispiel als

data Bar' r = Zero | Succ r 
type Bar f = fix (Bar' . f) 

Für jedes Paar von natürlichen Transformationen anders formulieren können eta1 :: f ~> g und eta2 :: Bar' ~> h wir bekommen eine natürliche Transformation (eta2 . eta1) :: (Bar' . f) ~> (h . g). Und wir können diese natürliche Transformation über den Fixpunkt in der offensichtlichen Weise aufheben, um fixed (eta2 . eta1) :: Bar f -> fix (h . g) zu erhalten. Daher ist Ihr "verschachtelter Homomorphismus" nur ein Sonderfall dieser Konstruktion, wenn wir eta2 = id haben.

Insgesamt ist dies eine ziemlich Standardkonstruktion (besonders für die Fälle, in denen f eine Monade oder comonad ist), obwohl ich nicht sicher bin, ob es einen bestimmten Namen hat, der weithin anerkannt ist.

Verwandte Themen