2013-01-20 47 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 

có ai biết tại sao điều này sẽ xảy ra không?lỗi phân đoạn haskell với giai thừa

fac 10000 làm việc

chạy trên OS X 10.8.2

hmm, việc nạp từ file:

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

chạy.

cũng thú vị là sử dụng

fac :: Int -> Int

lợi nhuận 0 cho fac 100000. Tôi đã mong đợi (giống như JohnL) một lỗi.

this site đề cập:

  • Cụ thể hơn, SegmentationFault là một cách một ngôn ngữ kiểu không an toàn thích rõ ràng DoesNotUnderstand. Trong một ngôn ngữ gõ tĩnh kiểu như Haskell, bạn không nên thấy các segfaults.

có liên quan gì đến trình đơn IO không?

+0

Nếu bạn định giảm giá, vui lòng giải thích tại sao. – beoliver

+3

Tôi không chắc có đủ thông tin ở đây để chẩn đoán sự cố. Điều này là vững chắc trong thể loại "không bao giờ nên xảy ra" vì vậy một cái gì đó rất lạ đang xảy ra với hệ thống của bạn. –

+0

'fac 100000 :: Số nguyên cho số 456574 chữ số trên os x tại đây. 'fax 100000 :: Int' là' 0 :: Int', vì, để đặt nó một chút thô lỗ, đó là bội số của 2^32 (hoặc 2^64). – applicative

Trả lời

2

Từ một thử nghiệm nhanh, có vẻ như là do thực tế là product không nghiêm ngặt và chuỗi khối gây ra lỗi.

Trong khúc dạo đầu, product được định nghĩa là:

product = foldl (*) 1 

Nếu trong ghci, bạn thay vì định nghĩa nó như:

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

Sau đó, nó sẽ làm việc. Tôi nghi ngờ khi bạn chỉ định chữ ký loại, có thể một số tối ưu hóa là đá trong đó không phải là hiện tại nếu không ... nhưng chưa đào vào nó.

Btw, bạn không cần dòng let fac 0 = 1.

+0

Nguyền rủa bạn ác' foldl' !!! – beoliver

1

Bằng cách cho nó một loại chữ ký

fac :: Integer -> Integer

nó sẽ làm việc. Tôi không hoàn toàn hiểu tại sao mặc dù.

+0

Nó có hoạt động nếu bạn cho chữ ký kiểu 'fac :: Int -> Int'? Tôi nghi ngờ rằng cũng sẽ segfault. –

+0

@JohnL sử dụng 'fac :: Int -> Int' thực sự trả về' 0' cho 'fac 100000' – beoliver