2017-09-24 3 views
0

Ich bin sehr neu zu Haskell und ich versuche, eine grundlegende Funktion, die den Mittelwert einer Liste findet. Ich habe es fast gelöst, abgesehen von dem letzten Teil der Trennung, den ich machen muss.Division von zwei Funktionen in Haskell

randInts = take 5 $ randoms (mkStdGen 11) :: [Int] 

listSum :: (Num a) => [a] -> a 
listSum [] = 0 
listSum (x:xs) = x + listSum xs 

listLength :: (Num a) => [a] -> a 
listLength [] = 0 
listLength (x:xs) = 1 + listLength xs 

listMean :: (Num a) => [a] -> a 
listMean [] = 0 
listMean x = (listSum x)/(listLength x) 

Dies ist, was mit Ich begann, wo listSum und ListLength grundsätzlich die gleiche Funktionalität auf Listen wie die Summe und die Länge Operatoren haben jeweils und listMean nimmt diese beiden und sie trennt. Als ich das laufen, aber ich erhalte eine Fehlermeldung sagen „ableiten kann nicht (Fractional a) von einer Verwendung von‚/‘aus dem Kontext ergeben: Num a“

Zuerst dachte ich nur, ich hätte verwendet der falsche Typ und die geschaltete ListeMit Startliste mit listeMean :: (Fraktional a) => [a] -> a. Dies ermöglichte mir das Kompilieren, aber als ich versuchte, es auszuführen, indem ich ihm randInts gab, erhielt ich stattdessen die Fehlermeldung "Keine Instanz für (Fractional Int), die sich aus einer Verwendung von 'listMean' ergibt."

Ich bin mir nicht sicher, was ich hier vermisse. Könnte ich bitte einen Rat bekommen?

+0

Sie meinen, fraktional zu entfernen? Ich tat das und es gab mir eine Fehlermeldung "Erwarte einen Typ, aber 'a' hat Art 'Constraint'" –

+0

Das gibt mir den Fehler "Keine Instanz für (Fractional Int) aus einer Verwendung von 'ListMean'" –

Antwort

2

Bei einer Schätzung: Sie testen dies in Ghci mit listMean randInts. Dies ist ein Problem, da Int Division nicht unterstützt über (/) sondern unterstützt ganzzahlige Division über div (um eine bestimmte Klasse von Fehlern zu vermeiden, die in Sprachen auftritt, die die beiden zusammenführen).

Sie haben eine zwei offensichtliche Wahl, nämlich Ihre Int s etwas umwandeln, die Support-Abteilung tut (z Double) oder erzeugen zufällige Double s in dem ersten Platz.

listMean (map fromIntegral is) :: Double 
listMean . take 5 . randoms $ mkStdGen 11 :: Double 

By the way, wenn meine Vermutung richtig ist: in die Zukunft, sollten Sie wirklich sind alle die Details der Dinge, die Sie haben, in so viel Detail, dass wir zusammen spielen zu Hause, sie folgen konnte und sehe den genau gleichen Fehler; und sollten Sie den gesamten Inhalt des Fehlers einbeziehen, zumal in diesem Fall das Code-Snippet erwähnt wird, das es verursacht hat und die Diagnose sofort gemacht hätte.

+0

I Ich hatte nicht daran gedacht, dies vorher mit einem Float zu testen, und ich sehe, dass es jetzt mit Float-Werten funktioniert. Danke für den Hinweis (obwohl ich jetzt komisch bin, habe ich Probleme, den Interpreter dazu zu bringen, einen Int in einen Float umzuwandeln) –

1

Das Problem ist, dass:

(Num a) => [a] -> a 

mit [Int] Angewandt, beide listSum und listLength kehrt Int, die nicht / unterstützt. Sie müssen die Rückgabewerte vor der Division konvertieren:

listMean :: (Num a, Integral a) => [a] -> Double 
listMean [] = 0 
listMean x = (fromIntegral $ listSum x)/(fromIntegral $ listLength x)