2013-06-28 8 views
5

Ich versuche immer noch sehr, in Haskell zu kommen, aber ich habe etwas bemerkt, das mich ziemlich verärgert hat.Warum wird in haskell nicht als Konvertierung behandelt?

Im Buch "Learn You a Haskell for Great Good!" gibt es diesen Teil, der die Verwendung von Wachen im Mustervergleich zeigt, im Fall des Buches war es eine kleine Funktion, die den BMI einer Person berechnet, es ging ein bisschen so (Teile geändert verletzen sie leicht auf nicht urheberrechtlich oder was auch immer):

bmiCalc :: (RealFloat a) => a -> a -> String 
bmiCalc weight height 
    | bmi <= 18.5 = "skinny" 
    | bmi <= 25.0 = "normal" 
    | bmi <= 30.0 = "fat" 
    | otherwise = "obese" 
    where bmi = weight/height^2 

das ist alles in Ordnung und gut der Code wie in der Werbung funktioniert, aber ich dachte, was ist, wenn es zeigte auch, was die bmi war es zusammen mit dem Text berechnet?

Also ich wieder schrieb den Code dazu:

bmiCalc :: (RealFloat a) => a -> a -> String 
bmiCalc weight height 
    | bmi <= 18.5 = "skinny, " ++ show bmi 
    | bmi <= 25.0 = "normal, " ++ show bmi 
    | bmi <= 30.0 = "fat, " ++ show bmi 
    | otherwise = "obese, " ++ show bmi 
    where bmi = weight/height^2 

"Show" Expecting ich falsch zu arbeiten wie .toString funktioniert in Java und C#
Junge war.

GHCI gab mir diese große böse Fehlermeldung:

Could not deduce (Show a) arising from a use of `show' 
from the context (RealFloat a) 
    bound by the type signature for 
      bmiCalc :: RealFloat a => a -> a -> String 
    at file.hs:1:16-48 
Possible fix: 
    add (Show a) to the context of 
    the type signature for bmiCalc :: RealFloat a => a -> a -> String 
In the second argument of `(++)', namely `show bmi' 
In the expression: "skinny, " ++ show bmi 
In an equation for `bmiCalc': 
    bmiCalc weight height 
     | bmi <= 18.5 = "skinny, " ++ show bmi 
     | bmi <= 25.0 = "normal, " ++ show bmi 
     | bmi <= 30.0 = "fat, " ++ show bmi 
     | otherwise = "obese, " ++ show bmi 
     where 
      bmi = weight/height^2 
Failed, modules loaded: none. 

warum ist das so? Warum erlaubt es mir nicht, etwas an eine Saite anzuhängen, das scheinbar eine Saite zurückgibt? Ich meine, soweit ich das verstanden habe "skinny, " ++ show bmi ist eine Zeichenkette ... welche ist genau das, was die Signatur sagt, dass ich

zurückgeben muss, was habe ich hier falsch gemacht?

+1

Haben Sie den Vorschlag aus der Fehlermeldung (gleich nach "Mögliche Fehlerbehebung") versucht? – Yuras

+2

Das vergleichbare Java-Äquivalent wäre, dass 'show' eine Methode der' Show'-Schnittstelle ist, und Ihr Wert 'a' ist nicht erforderlich, um diese Schnittstelle zu implementieren, daher gibt es einen Fehler bei der Kompilierzeitprüfung Das Gleiche wäre in Java passiert. –

+0

Früher hatte die Typenklasse 'RealFloat'' Show' als eine der Voraussetzungen (via 'Num'), aber das hat sich vor nicht allzu langer Zeit geändert. LYAH ist in dieser Hinsicht veraltet (siehe http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101, Suche nach 'To join num') – yatima2975

Antwort

9

ändern die Art Signatur:

bmiCalc :: (RealFloat a, Show a) => a -> a -> String 

Da Sie die Member-Funktion show, von den Show typeclass verwenden möchten; aber Sie haben das in der Funktion constraint nicht angegeben, und ghci hat keine Möglichkeit, daraus zu schließen, dass es korrekt ist.

+0

Lustige Sache ist, ich habe versucht, dies vor und zu tun es hat nicht funktioniert ... irgendwie tut es das irgendwie ... danke sowieso! –

+5

Der einfachste Ausweg bei solchen Fehlern ist das Löschen der Typ-Signatur, das erneute Laden der Datei in ghci und das Eingeben von ': t bmiCalc'. So füge ich am Ende alle meine Signaturen hinzu. – mhitza

+0

netter Tipp vielen Dank! –

2

RealFloat ist kein darstellbarer Typ. Sie müssen eine Show-Einschränkung hinzufügen.

Verwandte Themen