2013-04-12 9 views
5

Uczę się Haskella i mam problem z podstawową funkcją silni od this tutorial.Podstawowa silnia Haskell nie wychodzi?

Zasadniczo mam zdefiniował silni jako takie:

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

typu sprawdza się:

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

który ma sens. Jednak zachowanie tej funkcji nie działa. Rezultatem jest (interactive): out of memory niezależnie od wejścia.

Prelude> factorial 5 
(interactive): out of memory 

muszę założyć, że jest to nieskończony rekurencyjne wywołanie prowadzi do wyczerpania błędu pamięci, ale nie jestem pewien, co mogło być przyczyną tego. To samo dzieje się z factorial 0, chociaż ja wyraźnie oświadczył, że jest to 1:

Prelude> factorial 0 
(interactive): out of memory 

Teraz tutaj jest dziwne część: Gdybym zdefiniować funkcję silni w pliku, to działa dobrze. Utworzyć plik tesths.hs s.t .:

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

Następnie, jeśli wrócę do GHCI i uruchomić :l tesths.hs mogę wykonać factorial 5 bez błędu.

Co tu się dzieje?

Odpowiedz

11

Zdefiniowano dwie funkcje, a nie jedną funkcję z dwoma przypadkami. Wypróbuj te same komendy, które po raz pierwszy wykonują :set -Wall, i powinieneś otrzymać ostrzeżenie shadowingu nazwy. Aby rozwiązać ten problem, zamiast tego spróbuj wykonać polecenie:

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

.

+0

Huh. Ma to sens, jak sądzę. To dziwne zachowanie. – Zyerah

+3

To jest. 'let ...' w ghci jest naprawdę 'let ... in'. Z pewnością nie jest to jedyna rzecz dziwna w przypadku ghci - wynik jest różnie wyświetlany w zależności od tego, czy jest to typ 'Show a => a',' Show a => IO a', czy 'IO()'. – ScootyPuff

+0

To ma sens. Jest to zależne od rodzaju danych wejściowych, które są potrzebne w prawie każdym języku – Zyerah

11

Można również użyć składni :{ ... :} dać wejście wielowierszowego:

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

Podobnie, można użyć trybu wielowierszowego i wcięcia z :set +m:

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

Uwaga pustej linii. Możesz wyłączyć tryb wielowierszowy za pomocą :unset +m.

Zobacz dokumentację na ten temat w dokumencie Section 2.4.3 of the GHC User's Guide, "[Using GHCi with] Multiline input".

4

Zauważ, że jest to dość jedna wkładka też:

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

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

Powiązane problemy