2013-04-12 3 views
5

Ich lerne Haskell und habe Probleme mit einer faktoriellen Funktion von this tutorial.Haskell basic factorial nicht beenden?

Im Grunde habe ich eine faktorielle als solche definiert:

Prelude> let factorial 0 = 1 
Prelude> let factorial n = n * factorial (n - 1) 

Die Art auscheckt:

Prelude> :t factorial 
factorial :: Num a => a -> a 

was Sinn macht. Das Verhalten dieser Funktion ist jedoch nicht. Es ergibt sich (interactive): out of memory egal was die Eingabe ist.

Prelude> factorial 5 
(interactive): out of memory 

Ich muß davon ausgehen, das ein unendlicher rekursiven Aufruf zu einem außerhalb des Speicherfehlers führt, aber ich bin mir nicht sicher, was es möglicherweise verursachen könnte. Das gleiche geschieht mit factorial 0, obwohl ich ausdrücklich diesem 1 sein deklariert haben:

Prelude> factorial 0 
(interactive): out of memory 

Nun, hier ist der seltsame Teil: Wenn ich die Fakultäts-Funktion in einer Datei definieren, es funktioniert gut. Ich erstelle eine Datei tesths.hs s.t .:

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

Dann, wenn ich GHCI zurück gehen und laufen :l tesths.hs, ich factorial 5 ohne Fehler ausführen kann.

Was geht hier vor?

Antwort

11

Zwei Funktionen wurden definiert, nicht eine einzige Funktion mit zwei Fällen. Probieren Sie die gleichen Befehle aus, nachdem Sie zuerst :set -Wall ausgeführt haben, und Sie sollten eine Warnmeldung zum Namenschatten erhalten. Um das Problem zu lösen, versuchen Sie

let factorial 0 = 1; factorial n = n * factorial (n - 1) 

stattdessen.

+0

Huh. Macht Sinn, nehme ich an. Das ist ein seltsames Verhalten. – Zyerah

+3

Es ist. 'lass ...' in ghci ist wirklich "lass ... in". Dies ist definitiv nicht das einzige, was an ghci etwas seltsam ist - ein Ergebnis wird unterschiedlich angezeigt, je nachdem, ob es vom Typ 'Show a => a ',' Show a => IO a' oder 'IO()' ist. – ScootyPuff

+0

Das macht ein bisschen Sinn. Es hängt von der Art der Eingabe ab, die in fast jeder Sprache benötigt wird: – Zyerah

11

Sie können auch die :{ ... :} Syntax mehrzeiliges Eingabe geben:

Prelude> :{ 
Prelude| let factorial 0 = 1 
Prelude|  factorial n = n * factorial (n - 1) 
Prelude| :} 
Prelude> factorial 10 
3628800 
Prelude> 

Ebenso können Sie mehrzeiligen Modus und Vertiefung mit :set +m verwenden:

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

Beachten Sie die leere Zeile. Sie können den Mehrkanalmodus mit :unset +m wieder ausschalten.

Siehe Dokumentation Section 2.4.3 of the GHC User's Guide, "[Using GHCi with] Multiline input" für diese Dokumentation.

4

Beachten Sie, dass es dieses hübsche Einzeiler ist auch:

let factorial n = product [1..n] 
+3

http://www.willamette.edu/~fuehr/haskell/evolution.html – leftaroundabout