Warum gibt es in Haskell keine einfache Syntax für Koproduktypen?

8

Produkttypen in Haskell sind leicht definierbar:

%Vor%

ist ein Produkt zweier Arten. Das Nebenprodukt zweier Typen ist

%Vor%

Aber während das Produkt leicht auf drei oder mehr Typen erweiterbar ist, erscheint es für Koprodukte nicht so einfach. Gibt es eine theoretische Begründung für diesen Unterschied oder ist der Grund rein technischer?

    
Mozibur Ullah 10.01.2013, 02:34
quelle

1 Antwort

22
%Vor%

Hier ist Fruit ein Koprodukt von Apple , Orange und Berry 1 .

Beachten Sie, dass nicht getaggte Unions nicht Co-Produkte sind.

1 : Nun, irgendwie. Fruit enthält auch ein zusätzliches Element, . Siehe unten.

Antwort auf die bearbeitete Frage

%Vor%

Sie meinen wahrscheinlich:

%Vor%

Wenn Sie data verwenden, haben Sie einen Produkttyp mit einem einzelnen Konstruktor namens Either definiert. Das ist vollkommen legal. Wenn Sie type verwenden, haben Sie Shape als anderen Namen für Either Circle Rectangle definiert, was ein Nebenprodukt von Circle und Rectangle ist.

Hask vs Set

Nennen wir die Kategorie der Typen und Funktionen in Haskell, Hask. Dies ist der übliche Name dafür. Es erfüllt die Definition für Kategorie, vorausgesetzt, Sie betrachten diese endlichen Dinge, die wir Computer nennen, nicht zu genau.

Und vergleichen wir Hask mit der Kategorie Set. Das ist natürlich, weil Hask eine konkrete Kategorie ist. Vergleichen Sie den Konstruktor (,) in Hask mit dem kartesischen Produkt in Set. Wenn wir das Produkt von Int und Int wollen, erhalten wir:

  • ⊥ ∈ (Int, Int) (in Hask), aber
  • ⊥ ∉ Int ⨯ Int (in Set).

Sie sehen also, dass der Typkonstruktor (,) nicht mit dem kartesischen Produkt identisch ist, da er ein zusätzliches Element enthält. Wir können das Argument für die disjunkte Vereinigung wiederholen:

  • ⊥ ∈ Either Int Int (in Hask), aber
  • ⊥ ∉ Int ⊔ Int (in Set).

In jedem Fall enthält die Struktur in Hask ein zusätzliches Element, , das die äquivalente Struktur in Set nicht hätte.

Hask vs Pointed Sets

Hask ist auch nicht die Kategorie der spitzen Sets. Zuallererst enthält Hask Morphismen, die keine zugespitzten Morphismen sind.

  1. Für jeden Typ T in Hask können wir eine Funktion T -> T so erstellen, dass f x = ⊥ für alle x . Daher muss der Basispunkt sein, wenn Objekte in Hask spitz sind. Beachten Sie, dass alle diese f strikte Funktionen sind.

  2. Allerdings sollte g eine beliebige Funktion sein (die korrekte Bezeichnung ist hier eigentlich "nicht-streng"). Nach der Definition der Strenge g ⊥ ≠ ⊥ . Mit # 1 widerspricht dies jedoch der Prämisse, dass Hask die Kategorie der spitzigen Mengen ist.

Zusätzlich sind die Produkt- und Koproduktstrukturen verschieden, ähnlich wie sich die Strukturen von den Strukturen von Set unterscheiden. Für Produkte

  • (⊥, ⊥) ∈ (Int, Int) (in Hask), aber
  • (⊥, ⊥) ∉ Int ⊗ Int (in Pointed Set).

Das folgt aus dem Problem mit Morphismen: In spitzen Mengen sind alle Funktionen streng - dies schließt Konstruktoren wie (,) ein. Das Nebenprodukt hat das gleiche Problem:

  • Left ⊥ ∈ Either Int Int (in Hask), aber
  • Left ⊥ ∉ Int ⊕ Int (in Pointed Set).

Fazit

Also, Set und Pointed Set sind beide nicht ganz gleich der Kategorie Hask. Wie in der Hask Seite im Haskell-Wiki vermerkt, sind die Typen "Produkt" und "Koprodukt" in Haskell einfach nicht vorhanden erfüllen nicht die Definition von kategorischen Produkten und Coprodukten. Genau genommen gibt es in Haskell keine Produkte und Coprodukte.

Das sind die schlechten Nachrichten. Es gibt gute Neuigkeiten.

  1. Betrachte alle strikten Funktionen und strikten Konstruktoren in Hask. Das Ergebnis ist eine Unterkategorie von Hask, die ebenfalls eine Unterkategorie von Pointed Set ist. Diese Unterkategorie ist eine kartesische geschlossene Kategorie.

  2. Betrachte alle totalen Funktionen in Hask und betrachte zwei Funktionen als den gleichen Morphismus, wenn sie die gleiche Ausgabe für jede Eingabe außer erzeugen. (Diese Ausgaben müssen nicht unbedingt sein, wenn Sie "total" definieren.) Das Ergebnis ist eine Unterkategorie von Set. Diese Unterkategorie ist eine kartesische geschlossene Kategorie.

Sie können also weiterhin mit kartesischen geschlossenen Kategorien arbeiten, solange Sie nach den richtigen Regeln spielen. Sie können sogar aus zwei verschiedenen Kategorien wählen, mit denen Sie arbeiten können! Wenn Sie jedoch nach diesen Regeln spielen, arbeiten Sie mit einer Teilmenge von Haskell.

Es gibt ein letztes bisschen gute Nachrichten. Strikte Funktionen können in Lazy-Funktionen geändert werden, ohne die Ausgaben des Programms als Ganzes zu ändern, vorausgesetzt, die strikte Version des Programms wird beendet. Sie können also so tun, als ob nicht existiert und etwas Arbeit mit der Kategorientheorie machen, aber trotzdem Programme schreiben, die eine faule Auswertung ausnutzen.

Zusammenfassung für den faulen

Vorgeben, dass Hask Produkte und Coprodukte hat, bringt Sie nicht in Schwierigkeiten.

    
Dietrich Epp 10.01.2013, 02:40
quelle