2010-05-17 4 views
130

Ich versuche, jede einfache Funktion zu definieren, die mehrere Linien in GHCI, nehmen Sie die folgenden als Beispiel umfasst:Wie definiert man eine Funktion in ghci über mehrere Zeilen hinweg?

let abs n | n >= 0 = n 
      | otherwise = -n 

ich nach der ersten Zeile durch Drücken der Eingabetaste habe versucht Bisher:

Prelude> let abs n | n >= 0 = n 
Prelude>   | otherwise = -n 
<interactive>:1:0: parse error on input `|' 

ich habe auch versucht, die :{ und :} Befehle zu verwenden, aber ich bekomme nicht weit:

Prelude> :{ 
unknown command ':{' 
use :? for help. 

ich bin mit G HC Interactive Version 6.6 für Haskell 98 unter Linux, was fehlt mir?

+19

Bitte aktualisieren Sie Ihre GHC-Installation. GHC 6.6 ist fast 5 Jahre alt! Die neuesten Versionen von Haskell finden Sie hier: http://haskell.org/platform –

+0

mögliche Duplikate von [Mehrzeilenbefehle in GHCi] (http://stackoverflow.com/questions/8443035/multi-line-commands-in- ghci) – Mark

+0

@Mark Dieses OP hat bereits die Lösungen für dieses Problem ausprobiert. Dieses Problem liegt an einem veralteten ghci, nicht an mangelndem Wissen darüber, was zu tun ist. Lösung hier: Upgrade. Lösung dort: benutze ': {', ':}'. – AndrewC

Antwort

112

für Wächter (wie Ihr Beispiel), können Sie eine Zeile nur setzen sich alles auf und es funktioniert (Wächter über Abstand do not care)

let abs n | n >= 0 = n | otherwise = -n 

, wenn Sie Ihre Funktion mit mehreren Definitionen schreiben wollen, dass Mustererkennung auf die Argumente, wie folgt aus:

fact 0 = 1 
fact n = n * fact (n-1) 

dann würden Sie Klammern verwenden, um mit Semikolons die Definitionen Trennung

let { fact 0 = 1 ; fact n = n * fact (n-1) } 
7

Wenn Sie wollen GHC nicht nur ein Upgrade für :{ und :}, müssen Sie alles auf eine Zeile schreiben:

> let abs' n | n >= 0 = n | otherwise = -n 

I‘ Mir ist keine einzige Definition in Haskell bewusst, dass in mehreren Zeilen geschrieben werden muss. Die oben funktioniert in der Tat in GHCi:

> :t abs' 
abs' :: (Num a, Ord a) => a -> a 

Für andere Ausdrücke, wie do Blöcke, Sie werden die Nicht-Layout-Syntax mit geschweiften Klammern und Semikolons (eugh) verwenden müssen.

43

Dan ist richtig, aber :{ und :} muss jeder erscheinen auf ihre eigene Linie:

> :{ 
> let foo a b = a + 
>   b 
> :} 
> :t foo 
foo :: (Num a) => a -> a -> a 

Diese interagiert auch mit dem Layout der Regel so, wenn do-Notation könnte es einfacher sein, Klammern zu verwenden und semi- Doppelpunkte explizit. Zum Beispiel versagt diese Definition:

> :{ 
| let prRev = do 
| inp <- getLine 
| putStrLn $ reverse inp 
| :} 
<interactive>:1:18: 
    The last statement in a 'do' construct must be an expression 

Aber es funktioniert, wenn Klammern und Semikolons werden hinzugefügt:

> :{ 
| let prRev = do { 
| inp <- getLine; 
| putStrLn $ reverse inp; 
| } 
| :} 
> :t prRev 
prRev :: IO() 

Dies wird nur wirklich wichtig, wenn Definitionen aus einer Datei einfügen, wo Einzug ändern könnte.

+0

Dies funktioniert nicht, wenn Sie eine Zeile haben, die auf '=' endet (mit der folgenden Definition in der nächsten Zeile), zumindest in Version 7.6.3. – AdamC

+0

Vielleicht scheitert das, weil die zweite und dritte Zeile des Letters nicht eingerückt sind ...? (Zwei weitere Leerzeichen.) – Evi1M4chine

195

GHCi verfügt nun über einen Mehrzeilen-Eingabemodus, aktiviert mit: set + m.Beispiel:

Prelude> :set +m 
Prelude> let fac 0 = 1 
Prelude|  fac n = n * fac (n-1) 
Prelude| 
Prelude> fac 10 
3628800 
+29

Wenn Sie den Multiline-Modus einstellen, verhält sich 'ghci' in diesem Zusammenhang ähnlich wie der Python-Interpreter. Sehr angenehm! Sie können tatsächlich eine '.ghci'-Datei in Ihrem Home-Verzeichnis erstellen, indem Sie': set + m' setzen und der Multiline-Modus wird bei jedem Start von 'ghci' zum Standard. – kqr

+2

Das ist wirklich großartig. Aber ich habe bemerkt, dass, wenn ich meine Eingabeaufforderung mit ': set prompt" λ "setze, die fortgesetzten Zeilen" Prelude "statt" λ "sagen. Irgendeine Möglichkeit, das zu umgehen? – abhillman

+2

Hier sehen Sie, wie der Patch eine neue Fortsetzungsansage definiert https://ghc.haskell.org/trac/ghc/ticket/7509#no1 – karakfa