www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

phy51km4n

Gepostet:
03.07.2008 19:25

Frage bezüglich Datentyp "Either"  
Also erstmal sind Folgende Datentypen gegeben:

data Either a b = Left a
| Right b

data Tuple a b c d = One a
| Two a b
| Three a b c
| Four a b c d

Nun lautet eine Aufgabe:
"Based on our definition of Tuple, write a function which takes a Tuple and returns either the value
(if it’s a one-tuple), a Haskell-pair (i.e., (’a’,5)) if it’s a two-tuple, a Haskell-triple
if it’s a three-tuple or a Haskell-quadruple if it’s a four-tuple. You will need to
use the Either type to represent this."

Warum funktioniert das hier nicht? :

fromTuple (One a) = a
fromTuple (Two a b) = (a, b)
fromTuple (Three a b c) = (a, b, c)
fromTuple (Four a b c d) = (a, b, c, d)

Und warum läuft das? :

fromTuple (One a ) = Left (Left a)
fromTuple (Two a b ) = Left (Right (a,b))
fromTuple (Three a b c ) = Right (Left (a,b,c))
fromTuple (Four a b c d) = Right (Right (a,b,c,d))

Warum funktioniert diese Andordnung von Lefts und Rights und vor allem: WIE funktioniert sie ??
Zum Seitenanfang    
 
Siracusa

Gepostet:
03.07.2008 21:15

   
Hallo,

das Problem wird klar, wenn du dir mal die Typen der beiden Ausdrücke genauer anschaust:
fromTupel (Two a b) = (a,b)
==> fromTuple :: (Tuple a b c d) -> (a,b)
fromTuple (Three a b c) = (a,b,c)
==> fromTuple :: (Tuple a b c d) -> (a,b,c)

Die selbe Funktion soll also Werte von zwei unterschiedlichen Typen liefern, was in Haskell zu einem Typfehler führt. 2-Tupel und 3-Tupel sind in Haskell unterschiedliche Typen. Ich glaube in Scheme o.ä. kann man 2-Tupel zu 3-Tupel erweitern, das geht in Haskell nicht.

fromTuple (One a) = Left (Left a)
==> fromTuple :: (Tuple a b c d) -> Either (Either a x) y // x und y sind hier noch beliebig
fromTuple (Two a b) = Left (Right (a,b))
==> fromTuple :: (Tuple a b c d) -> Either (Either a (a,b)) y // über x wissen wir nun schon mehr, über y noch nicht
fromTuple (Three a b c) = Right (Left (a,b,c))
==> fromTuple :: (Tuple a b c d) -> Either (Either a (a,b)) (Either (a,b,c) z) // y ist nun spezieller geworden, dafür ist z beliebig
fromTuple (Four a b c d) = Right (Right (a,b,c,d))
==> fromTuple :: (Tuple a b c d) -> Either (Either a (a,b)) (Either (a,b,c) (a,b,c,d)) // Der Typ von fromTuple ist nun so speziell wie möglich geworden

Ein Funktionsergebnis (Left x) sagt also etwas über den Typ aus, der im Left gekapselt ist; über den im Right gekapselten Typ noch gar nichts, dieser ist völlig frei wählbar. Wird die Funktion um ein Funktionsergebnis (Right y) erweitert, dann muß der Ergebnistyp (Either (Typ von x) (Typ von y)) sein. Analog funktioniert das auch mit verschachtelten Eithers.
Du kannst ja mal eine Zeile der Funktionsdefinition auskommentieren und dir dann im Interpreter den Typ der Funktion ausgeben lassen (mit :type fromTuple). Dann müßte im Ergebnistyp eine Stelle in den Either-Verschachtelungen wieder weniger speziell werden.

Ich hoffe das war jetzt einigermaßen verständlich, falls nicht, einfach nochmal nachfragen. :-)


Viele Grüße,

Siracusa
Zum Seitenanfang