2017-10-06 25 views
2

übereinstimmen Ich versuche also, eine Hilfsfunktion zu erstellen, die etwas anderes tut, aber ich kann nicht einmal bekommen hinter der Helferfunktion, weil ich diesen Fehler immer wieder bekomme:Der erwartete Typ '[Char]' konnte nicht mit dem tatsächlichen Typ 'Int -> [t -> t1]'

Das senkt (x) verursacht das Problem. Hier ist mein Code:

lowers [] = 0 
lowers (x:xs) 
    | isLower x == True = 1 + lowers xs 
    | otherwise = lowers xs 

count _ [] = 0 
count x (y:ys) 
    | x == y = 1 + count x ys 
    | otherwise = count x ys 

percent x y = x/y*100 

freqsHelper x = freqs (x (lowers x)) 

freqs (x:xs) y = percent ((count (x (x:xs))) y) : freqs xs y 
+1

Was sollen Freqs tun? – Carbon

+0

Wie Davislor und MathematicalOrchid empfehle ich Ihnen, die Typdeklarationen für jede Funktion zu schreiben, die Sie in der Zukunft schreiben. Am Ende sparen Sie viel Zeit, denn der Compiler kann schon früh erkennen, wo Sie schief gegangen sind. Das Typensystem ist eines der nettesten Dinge in Haskell, also sollten Sie es zu Ihrem Vorteil nutzen. Das Schreiben der Typdeklarationen hilft Ihnen auch, wenn Sie eine typisierte Programmierung durchführen müssen. Mit der Erweiterung 'InstanceSigs' können Sie auch eine Typdeklaration für Ihre Funktionen in jeder Instanz der Typklasse schreiben. –

Antwort

2

Sie wäre gut beraten, Typdeklarationen für jede Top-Level-Funktion hinzuzufügen. Folgen wir dem, was das Typabzugssystem hier macht, wenn es versucht, das herauszufinden.

Das Problem ist nicht mit lowers, die ein [Char] als sein Argument nimmt und eine Int zurückgibt. Die freqsHelper x Deklaration hat ein Argument, x, dessen Typ wir a nennen, während wir versuchen, es herauszufinden. Wir rufen den Rückgabetyp b auf. So ist freqsHelper eine Funktion des Typs a -> b.

Es ist auch gleich freqs (x (lowers x)). So muss x, der Typ a hat, eine Funktion sein, die das Ergebnis lowers als sein Argument nimmt. Wir wissen, dass lowers[Char] -> Int ist, also muss a eine Funktion des Typs Int -> t1 sein, wobei t1 eine Art ist, die wir von freqs ableiten müssten. Jedoch wird x auch als Argument von lowers übergeben. Was erwartet [Char], keine Funktion mit einem Argument. Wir haben also schon einen Widerspruch.

Also, da ist Ihre Diskrepanz. In der Definition von freqsHelper verwenden Sie x in einem Kontext, in dem Haskell eine Zeichenfolge erwartet, aber auch in einem Kontext, in dem x irgendeine Art von Funktion sein muss. Ich bin mir ziemlich sicher, dass es auch einen Fehler in freqs gibt, da er eine Funktion von zwei numerischen Argumenten mit nur einem Argument aufruft.

0

Ah, ich denke ich weiß, worauf Sie hinaus wollen. Du bist nah dran. Ein paar Dinge - wenn du eine Division machst, solltest du ein fromIntegral machen, um eine Art Bruch zurückzubekommen.

percent :: (Fractional a) => Int -> Int -> a 
percent x y = (fromIntegral x/fromIntegral y) * 100 

Ich denke, Ihre Frequenz versucht, die Frequenz von etwas in einer Liste zu bekommen, in dem Fall, dass Sie einen Basisfall benötigen:

freqs [] y = [] 
freqs (x:xs) y = percent (count x y) (length y) : freqs xs y 

Ich glaube, Sie den Rest herausfinden können, von Hier.

Einige Stil Hinweise - können Sie eine Karte für freqs verwenden:

freqs' x y = map (\a -> percent (count a y) $ length y) x 

Der Compiler tun es wahrscheinlich für Sie, aber Sie können Länge y explizit rufen:

freqs' x y = map (\a -> percent (count a y) len) x 
    where len = length y 
0
freqsHelper x = freqs (x (lowers x)) 

Lasst uns das kaputt machen.

lowers x 

Sie rufen lowers mit x als Eingabe, so x muss ein String sein.

x (lowers x) 

Aber Sie rufen x als Funktion, es das Ergebnis von lowers als Eingabe übergeben. So muss x eine Funktion sein, die einen Int als Eingabe nimmt. (Das klingt wie ein Fehler ...)

freqs (x (lowers x)) 

Sie rufen freqs mit dem Ausgang von dem Aufruf der Funktion x ... so x eine Liste irgendeiner Art zurückgeben muss?

An dieser Stelle ist der Typ Checker verwirrt, was zum Teufel x ist sogar sein soll, so gibt es auf.

Vielleicht sollten Sie x und lowers x als zwei separate Argumente übergeben? In diesem Fall möchten Sie

freqs x (lowers x) 

von Klammern um x (lowers x) setzen, machen Sie der Compiler denken, dass x eine Funktion Sie rufenden, mit lowers x als Argument. Ich bezweifle, dass du das wolltest.

Als Nebenbemerkung, wenn Sie Typ-Signaturen für jede der Funktionen, die Sie definiert haben, hinzufügen, erhalten Sie möglicherweise eine klarere Angabe von der Typprüfung, welches Bit tatsächlich falsch ist. (So ​​wie es ist, kann der Typüberprüfer sehen, dass die Typen sich nicht aufreihen, aber nicht bestimmen können, wo die Typen von dem abweichen, was Sie beabsichtigten —, weil es Ihre Meinung nicht lesen kann, um zu wissen, was Sie beabsichtigten)

Verwandte Themen