Die folgende Erklärung gibt einen Fehler aus:
type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
| Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
| Translate Vec3d Obj3d
nämlich Multiple declarations of 'Translate'
.
Nun frage ich mich, warum diese Einschränkung eingeführt wurde?
Wenn die Einschränkung nicht da wäre, könnte man schreiben
Translate (1, 1) Rect 2 2
und
Translate (1, 2, 3) Cuboid 1 1 1
das klingt natürlich.
Ich sehe nicht (sofort), wie dies zu einem Analyseproblem führen könnte, das die Verwendung desselben Namens verbietet. Der Typ könnte durch das Argument abgeleitet werden ( Rect 2 2
ist ein Obj2d
, Cuboid 1 1 1
ist ein Obj3d
).
Ich bin mir sicher, dass es einen guten Grund gibt, warum die Sprachdesigner die Verwendung des gleichen Namens für Datenkonstruktoren unterschiedlichen Typs nicht zulassen, aber ich möchte lernen: Warum, wenn dies nicht offensichtlich erforderlich ist?
(Und Typendisambiguierung ist das Brot-und-Butter-Geschäft von Haskell!)
Antworten:
Dies liegt daran, dass Datenkonstruktoren nur Funktionen sind und das Überladen von Funktionen in Haskell nicht zulässig ist. Es ist möglicherweise klarer, wenn Sie die GADT-Syntax verwenden, um Ihre Typen zu definieren:
Ich glaube, sie (die GHC-Entwickler) arbeiten an möglichen Lösungen für dieses Problem, indem sie eine neue
type class
für alle Typen einführen , die denselben Datenkonstruktor oder ähnliches verwenden. Bleiben Sie also auf dem Laufenden, eine Lösung für Ihr Problem könnte bald kommen! (Ich hoffe)quelle
type class
Konstrukte, die Sie festlegen. - Der Grund ist: Ich habe kein Problem, ich kannTranslate2
undTranslate3d
, aber ich möchte den Namespace lieber nicht verschmutzen.