Algebraische Typen
 
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

(von SprachePerl)

Algebraische Typen sind die Mechanismen, mit denen man aus primitiven Datentypen neue definiert. In Sprachen wie Haskell oder ML sind die grundlegenden Mittel dafür:

  data IntOrFloat? = AnInt? Int | AFloat Float

  data TwoInts? = Two Int Int

  type ShowS? = String -> String

Defintionen dürfen rekursiv sein, und in modernen Sprachen mit Typvariablen parametrisiert werden. So sehen dann Listen und binäre Suchbäume aus:

  data List element = Cons element (List element) | Nil
  data Tree key = Node (Tree key) key (Tree key) | Leaf

Erzeugt werden solche Daten durch Anwendung der Konstruktoren auf geeignete Argumente. Das ist beispielsweise eine Liste von zwei Ganzzahlen:

  Cons 1 (Cons 2 Nil)

Zerlegt werden sie in Haskell oder ML durch PatternMatching. So definiert man etwa eine Funktion, die das erste Element einer Liste ermittelt:

  head (Cons x ys) = x
  head Nil         = error "head of empty list"

Sprachen wie C, Pascal, Java haben natürlich ihren eigenen Ersatz. Jedoch muss Rekursion über Pointer oder Referenzen explizit gemacht werden und die Zerlegung von Unions (so es welche gibt) ist immer etwas unsicher, weil nicht sichergestellt ist, dass nicht auf einen gerade undefinierten Zweig einer Union zugegriffen wird.

Die Vorteile von algebraischen Typen und Pattern Matching liegen auf der Hand:


...obwohl ich das Gewicht nicht verstehe, das du den Unions gibst. -- HelmutLeitner

Nur in Verbindung mit Pattern Matching. Betrachten wir eine Funktion, die ein Ergebnis liefern kann oder auch nicht, nämlich die Lösung einer quadratischen Gleichung. Die hat entweder keine Lösung oder eine oder zwei. Wie implementiert man das? In C vermutlich, indem man sich die Anzahl der Lösungen als Ergebnis geben läßt und die Ergebnisse selbst in zwei referenzierten Variablen ablegen läßt.

  int solve_quadratic( double a, double b, double c, double *x1, double *x2 ) ;

Mit alg. Summen läßt man sich das Ergebnis einfach geben wie es ist:

  data Solution = None | One Double | Two Double Double
  solve_quadratic :: Double -> Double -> Double -> Solution

...und es besteht keine Gefahr, eine "Lösung" anzufassen, die gar nicht berechnet wurde.

Oder wir betrachten eine Funktion, die fehlschlagen kann, weil irgendwas nicht ist, wie es sein sollte (ExceptionHandling? sozusagen). Die kann dann ein Ergebnis oder einen Fehler liefern.

  data Either a b = Left a | Right b
  openFile :: FilePath? -> Either Error Handle

Praktischerweise ist es unmöglich, die Fehlerbehandlung zu vergessen. Um nämlich an das Handle zu kommen, muss man auf den Konstruktor Right matchen, und das geht nicht, wenn es in Wirklichkeit einen Fehler gab.

  case openFile "foo" of
    Right hdl -> hPutStr hdl "bar"
    Left err  -> print "the sky is falling!"


StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 24. November 2005 14:52 (diff))
Suchbegriff: gesucht wird
im Titel
im Text