Gepostet: |
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 | |||||||||||
Gepostet: |
|||||||||||
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 | |||||||||||