Ich habe Probleme bei der Eingabe mehrzeiliger Befehle in ghci.
Der folgende zweizeilige Code funktioniert aus einer Datei:
addTwo :: Int -> Int -> Int
addTwo x y = x + y
Aber wenn ich in ghci eingebe, erhalte ich eine Fehlermeldung:
<interactive>:1:1: error:
Variable not in scope: addTwo :: Int -> Int -> Int
Ich habe auch versucht, den Code einzufügen :{ ... :}
, aber sie funktionieren auch in diesem Beispiel nicht, da hier nur die Zeilen in eine Zeile angehängt werden, was nicht der Fall sein sollte.
Ich verwende WinGHCi, Version 2011.2.0.1
Antworten:
Meistens können Sie sich auf Typinferenz verlassen, um eine Signatur für Sie zu erstellen. In Ihrem Beispiel ist Folgendes ausreichend:
Wenn Sie wirklich eine Definition mit einer Typensignatur wünschen oder Ihre Definition sich über mehrere Zeilen erstreckt, können Sie dies in ghci tun:
Beachten Sie, dass Sie dies auch auf eine Zeile drücken können:
Weitere Informationen zur Interaktion mit ghci finden Sie in der interaktiven Evaluierung im Eingabeaufforderungsabschnitt der Dokumentation.
quelle
let
beginnt einen Block; Einträge in einem Block werden nach Einrückung gruppiert. und das erste Nicht-Leerzeichen in einem Block legt den Einzug fest, nach dem sie gruppiert sind. Da das erste Nicht-Leerzeichen imlet
obigen Block dasa
von istaddTwo
, müssen alle Zeilen im Block genau so tief eingerückt seina
.Lösen Sie dieses Problem, indem Sie GHCI starten und Folgendes eingeben
:set +m
:Boom.
Was hier vor sich geht (und ich spreche hauptsächlich mit Ihnen , einer Person, die um Hilfe googelt, während Sie sich durch Learn You A Haskell arbeiten ), ist, dass GHCI eine interaktive Umgebung ist, in der Sie die Bindung von Funktionsnamen im laufenden Betrieb ändern. Sie müssen Ihre Funktionsdefinitionen in einen
let
Block einschließen, damit Haskell weiß, dass Sie etwas definieren werden. Das:set +m
Zeug ist eine Abkürzung für das mehrzeilige:{
Codekonstrukt:}
.Leerzeichen sind auch in Blöcken von Bedeutung. Daher müssen Sie Ihre Funktionsdefinition nach Ihrer Typdefinition um vier Leerzeichen einrücken, um die vier Leerzeichen in zu berücksichtigen
let
.quelle
echo ':set +m' >> ~/.ghci
um diese Einstellung dauerhaft zu machen.let
für sich in der ersten Zeile haben, dann muss der Rest überhaupt nicht eingerückt werden. Wenn das Leerzeichen wirklich zählt, dürfen in Ihren Zeilen keine nachgestellten Leerzeichen stehen. Nachfolgendes Leerzeichen zählt als zusätzliche Eingabe und unterbricht den mehrzeiligen Block.Verwendung
let
:quelle
Ab GHCI Version 8.0.1 ,
let
ist nicht mehr auf dem REPL definieren Funktionen erforderlich.Das sollte also gut für Sie funktionieren:
Die Typinferenz von Haskell bietet eine allgemeine Typisierung, die auch für Floats funktioniert:
Wenn Sie Ihre eigene Eingabe angeben müssen, müssen Sie anscheinend eine
let
Kombination mit einer mehrzeiligen Eingabe verwenden (verwenden Sie:set +m
diese Option, um die mehrzeilige Eingabe in GHCI zu aktivieren):Sie erhalten jedoch Fehler, wenn Sie
Int
aufgrund Ihrer nicht polymorphen Typisierung versuchen, etwas anderes als ein zu übergeben :quelle
Um die Antwort von Aaron Hall zu erweitern , müssen Sie zumindest in Version GHCi 8.4.4 keine
let
Typdeklarationen verwenden, wenn Sie den:{
:}
Stil verwenden. Dies bedeutet, dass Sie sich nicht um das Hinzufügen der 4-Leerzeichen-Einrückung in jeder nachfolgenden Zeile kümmern müssen, um dies zu berücksichtigenlet
, wodurch längere Funktionen viel einfacher eingegeben oder in vielen Fällen kopiert und eingefügt werden können (da die ursprüngliche Quelle dies wahrscheinlich nicht hat die richtige Einrückung):Aktualisieren
Als Alternative Sie mit auf mehrzeiliges Eingabemodus schalten kann
:set +m
, geben Sie dannlet
auf seine eigene, drücken Sie die Eingabetaste, dann fügen Sie Definitionen ohne Vertiefung erforderlich.Dies scheint jedoch bei einigen Codeblöcken nicht zu funktionieren, z.
Aber die
:{
,:}
Technik der Fall ist.quelle
:{
in die nächste Zeilelet
selbst eingeben, dann Ihre Definitionen ohne zusätzlichen Einzug einfügen und dann mit schließen:}
. :) und mit dem mehrzeiligen Eingabemodus set (:set +m
) brauchten Sie nicht einmal die geschweiften Klammerbefehle, solange die Codezeilen keine nachgestellten Leerzeichen enthielten.:set +m
dir kann man einfachlet
auf einer eigenen Leitung verwenden? Also kannst du - das ist cool. Danke dir.let
dann der Zeilenumbruch nicht funktioniert. Siehe meine Bearbeitung.