2012-12-15 11 views
5

Lassen Sie uns sagen, dass ich einen Baum wie folgt definieren wollen:Alternative für veralteten -XDatatypeContext?

{-# LANGUAGE DatatypeContexts #-} 
class Node a where 
    getContent :: (Num a) => a 

data (Node a) => Tree a = Leaf a 
         | Branch a (Tree a) (Tree a) 

-XDatatypeContexts jetzt ist veraltet. Ist es möglich, etwas Ähnliches ohne es zu tun?

Antwort

13

Sind Sie sicher Datatype Kontexte tat tatsächlich, was Sie denken, dass es getan hat? Es war deprecated because it was basically useless und wurde weithin als Fehlfunktion betrachtet, da es nur dazu führte, dass Sie zusätzliche Beschränkungen hinzufügten, ohne irgendwelche Garantien über Typen zu geben, die über das hinausgehen, was Sie ohne es gehabt hätten.

Der Ersatz, wie es ist, dass tatsächlich tut etwas Nützliches, ist GADT syntax.

data Tree a where 
    Leaf :: (Node a) => a -> Tree a 
    Branch :: (Node a) => a -> Tree a -> Tree a -> Tree a 

In diesem Fall müssen Sie die Node Einschränkung bei der Erstellung eines Tree Wert, aber wenn Pattern-Matching auf einem Tree Wert erhalten Sie auch eine automatische Garantie, dass ein Node Beispiel: Das Äquivalent von Ihrer Art würde wie folgt aussehen existiert, macht die Instanz verfügbar, ohne sie in dem Typ der Funktion zu benötigen, die als Argument erhält.

+0

Vielen Dank! Obwohl ich denke, du meinst Branch :: (Knoten a) => a -> Baum a -> Baum a – Jake

+0

@Jake: Nein - es funktioniert genau wie eine Funktionstyp Signatur, so dass die letzte 'Tree a' ist das Ergebnis Datentyp. 'a -> Baum a -> Baum a 'hätte nur einen Unterbaum. Vergleichen Sie den Typ des 'Branch'-Konstruktors, den Sie gerade haben. –

+0

Oh, richtig, ich verstehe. – Jake