2013-01-20 19 views
6
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Prelude> let fac 0 = 1 
Prelude> let fac n = product [1..n] 
Prelude> fac 100000 
Segmentation fault: 11 

qualcuno ha idea del motivo per cui ciò avverrebbe?errore di segmentazione haskell con fattoriale

fac 10000 funziona

in esecuzione su OS X 10.8.2

hmm, in modo da caricare un file:

fac :: Integer -> Integer 
fac 0 = 1 
fac n = product [1..n] 

piste.

anche interessante è che l'utilizzo

fac :: Int -> Int

rendimenti 0 per fac 100000. Mi sarei aspettato (proprio come JohnL) un errore.

this site menzioni:

  • Più in particolare, SegmentationFault è un modo un linguaggio di tipo non sicuro incantesimi DoesNotUnderstand. In un linguaggio tipicamente tipizzato come Haskell, non dovresti vedere i segfault.

è qualcosa a che fare con la monade IO?

+0

Se si sta andando a downvote, per favore almeno spiegare perché. – beoliver

+3

Non sono sicuro che ci siano abbastanza informazioni qui per diagnosticare il problema. Questo è saldamente nella categoria di "non dovrebbe mai accadere", quindi qualcosa di molto strano sta succedendo con il tuo sistema. –

+0

'fac 100000 :: Integer' fornisce un numero di 456574 cifre su os x qui. 'fax 100000 :: Int' è' 0 :: Int', poiché, per dirla in modo un po 'rozzo, è un multiplo di 2^32 (o 2^64). – applicative

risposta

2

Da un test rapido, sembra essere causato dal fatto che product non è rigido e la catena di thunk causa l'errore.

Nel preludio, product è definito come:

product = foldl (*) 1 

Se in ghci, voi invece lo definiscono come:

> :m + Data.List 
> let product = foldl' (*) 1 
> let fac n = product [1..n] 

allora dovrebbe funzionare. Sospetto che quando specifichi la firma del tipo, forse è in corso qualche ottimizzazione che non è presente altrimenti ... ma non l'hai scavata.

Btw, non è necessaria la riga let fac 0 = 1.

+0

Maledico' foldl' !!! – beoliver

1

dandogli un tipo di firma

fac :: Integer -> Integer

che funzionerà. Non capisco perfettamente perché però.

+0

Funziona se si assegna la firma di tipo 'fac :: Int -> Int'? Sospetto che anche segfault. –

+0

@JohnL usando 'fac :: Int -> Int' restituisce effettivamente' 0' per 'fac 100000' – beoliver