www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

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

Logo - DracheHaskell-Forum

SanjoNinjaPanda

Gepostet:
30.10.2011 11:29

Fehlermeldung: Undefined type constructor  
Hallo liebe HaskellGemeinde!

ich bin Einsteiger und hab vorher keine Sprache gelernt. Mein Programm compiliert nicht. Hab die Suche genutzt -nix.
Wäre sehr dankbar wenn mir vielleicht hier jemand helfen könnte?

Mein Code ist:



-- Die Funktion dreiWerte soll ausgeben wieviele von drei Werten größer als der Durchschnittswert sind.


dreiWerte :: Integer -> Integer -> Integer -> Str

dreiWerte a b c
| a > (a+b+c)/2 && b > (a+b+c)/2 && c > (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Drei Werte sind größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a > (a+b+c)/2 && b > (a+b+c)/2 && c < (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Zwei Werte sind größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a > (a+b+c)/2 && b < (a+b+c)/2 && c > (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Zwei Werte sind größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a > (a+b+c)/2 && b < (a+b+c)/2 && c < (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Ein Wert ist größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a < (a+b+c)/2 && b > (a+b+c)/2 && c > (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Zwei Werte sind größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a < (a+b+c)/2 && b > (a+b+c)/2 && c < (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Ein Wert ist größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a < (a+b+c)/2 && b < (a+b+c)/2 && c > (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Ein Wert ist größer als der Durchschnitt\\\\\\\\\\\\\\\"
| a < (a+b+c)/2 && b < (a+b+c)/2 && c < (a+b+c)/2 = putStrLn \\\\\\\\\\\\\\\"Kein Wert ist größer als der Durchschnitt\\\\\\\\\\\\\\\"


Der Compiler sagt:
ERROR file:.\\\\\\\\\\\\\\\\dreiWerte.hs:4 - Undefined type constructor \\\\\\\\\\\\\\\"Str\\\\\\\\\\\\\\\"

Anmerkung: Die Backslashes überall wo ein String ist sind nicht von mir sondern von Jammi. Kann ich nicht abstellen.

Wo ist denn der Fehler?
Hab dann erst blind versucht das putStrLn wegzulassen -nix.
Andere Idee hab ich nicht mehr. Ich weiß nicht was er hat :(

Gruß
SanjoNinjaPanda


Zum Seitenanfang    
 
SanjoNinjaPanda

Gepostet:
30.10.2011 11:34

Berichtigung  
Sorry Doppelpost!
Zum Seitenanfang    
 
Viviane

Gepostet:
30.10.2011 14:58

   
Hallo.

1.: Tatsächlich das putStrLn weglassen.

2.: Er kennt den Typ Str nicht. Das ganze ist ein String.

Dann schreibe das auch oben in die Typdeklaration.

Zum Seitenanfang ICQ    
 
Landei

Gepostet:
01.11.2011 11:14

   
Noch mehr Fehler: Der Durchschnitt wäre rein mathematisch (a+b+c)/3 und nicht (a+b+c)/2. Allerdings gibt es noch ein Problem mit /, weil das nur für Realzahlen definiert ist, nicht für Ganzzahlen: Dort lautet der entsprechende Operator div, aber du willst ja sicher den exakten Durchschnitt, nicht die abgerundete Version.

Ich würde vorschlagen, gleich mit Realzahlen zu arbeiten (ansonsten müsstest du die Funktion fromIntgral verwenden). Also definieren wir erst einmal den Durchschnitt:


avg :: Double -> Double -> Double -> Double
avg a b c = (a+b+c)/3.0


Nun suchen wir noch einen einfacheren Weg, um die Anzahl der Werte kleiner/gleich/größer dem Durchschnitt zu bestimmen. Mit filter können wir alle Elemente einer Liste ermitteln, die ein gegebenes Kriterium erfüllen, und mit length ermitteln wir die Länge der Ergebnisliste:


smaller, same, bigger :: Double -> Double -> Double -> Int
smaller a b c = length (filter (< avg a b c) [a,b,c])
same a b c = length (filter (== avg a b c) [a,b,c])
bigger a b c = length (filter (> avg a b c) [a,b,c])


Das sieht sehr nach Wiederholung aus, also vergessen wir diese Funktionen gleich wieder und verallgemeinern sie lieber zu einer einzigen, der wir noch den gewünschten Operator übergeben:


cmp :: Double -> Double -> Double -> (Double -> Double -> Bool) -> Int
cmp a b c op = length (filter (`op` (avg a b c)) [a,b,c])


Jetzt können wir map verwenden, um die die verschienedenen Operationen bequem an cmp zu \"verteilen\":


cmps :: Double -> Double -> Double -> [Int]
cmps a b c = map (cmp a b c) [(<),(==), (>)]


Das Ergebnis ist eine Liste mit der Anzahl der kleineren, gleichen und größeren Elementen. Jetzt ist dreiWerte trivial:


dreiWerte :: Double -> Double -> Double -> String
dreiWerte a b c = say (cmps a b c) where
say [0,0,3] = \"Drei Werte größer als der Durchschnitt\"
say [0,1,2] = \"Zwei Werte größer als der Durchschnitt\"
...


Ich hoffe, ich habe dich jetzt nicht zu sehr verwirrt...
Zum Seitenanfang    
 
SanjoNinjaPanda

Gepostet:
01.11.2011 22:12

   
Dankeschön Viviane genau die beiden Sachen waren es.
@ Landei:
Wow!
Ich verstehe es noch nicht ganz. Kann ich morgen eine Frage dazu stellen?
Zum Seitenanfang    
 
Landei

Gepostet:
02.11.2011 10:12

   
Jederzeit :-)
Zum Seitenanfang    
 
Landei

Gepostet:
02.11.2011 23:18

   
Ich sehe gerade, dass du nur wissen willst, wieviel Werte größer als der Durchschnitt sind (und nicht, wieviel kleiner oder gleich sind). Dann reicht avg und bigger aus:


avg :: Double -> Double -> Double -> Double
avg a b c = (a+b+c)/3.0

bigger :: Double -> Double -> Double -> Int
bigger a b c = length (filter (> avg a b c) [a,b,c])

dreiWerte :: Double -> Double -> Double -> String
dreiWerte a b c = ([\"Kein Wert\", \"Ein Wert\",\"Zwei Werte\",\"Drei Werte\"] !! (bigger a b c)) ++ \" größer als der Durchschnitt\"
Zum Seitenanfang