2011-07-17 27 views
36

Tôi gặp sự cố. Tôi đã viết một chương trình Haskell lớn và nó luôn hoạt động với đầu vào nhỏ. Bây giờ, khi tôi muốn thử nghiệm nó và tạo ra một đầu vào lớn hơn, tôi luôn nhận được thông báo:Làm thế nào để gỡ lỗi mã Haskell?

HsProg: Prelude.head: empty list 

tôi sử dụng Prelude.head nhiều lần. Tôi có thể làm gì để tìm hiểu thêm hoặc có được một đầu ra lỗi tốt hơn để có được dòng mã mà nó xảy ra?

+0

bạn sử dụng interpiter hoặc trình biên dịch nào? – Sudantha

+0

i sử dụng: GHC 7.0.3 – haskellNewcommer

+0

Hy vọng điều này sẽ giúp bạn [Làm thế nào để “gỡ rối” Haskell với printfs?] [1] [1]: http://stackoverflow.com/questions/3546592/how-to-debug-haskell-with-printfs – Sudantha

Trả lời

67

Tùy chọn GHCi -fbreak-on-exception có thể hữu ích. Đây là một phiên gỡ lỗi ví dụ. Trước tiên, chúng tôi tải tập tin của chúng tôi vào GHCi.

$ ghci Broken.hs 
GHCi, version 7.0.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. 
Loading package ffi-1.0 ... linking ... done. 
[1 of 1] Compiling Main    (Broken.hs, interpreted) 
Ok, modules loaded: Main. 

Bây giờ, chúng tôi bật -fbreak-on-exceptions và theo dõi biểu hiện của chúng tôi (main trong trường hợp này cho toàn bộ chương trình).

*Main> :set -fbreak-on-exception 
*Main> :trace main 
Stopped at <exception thrown> 
_exception :: e = _ 

Chúng tôi đã dừng lại ở một ngoại lệ. Hãy thử xem mã với :list.

[<exception thrown>] *Main> :list 
Unable to list source for <exception thrown> 
Try :back then :list 

Vì ngoại lệ xảy ra trong Prelude.head, chúng tôi không thể xem trực tiếp nguồn. Nhưng như GHCi thông báo cho chúng tôi, chúng tôi có thể đi :back và cố gắng liệt kê những gì đã xảy ra trước đó trong dấu vết.

[<exception thrown>] *Main> :back 
Logged breakpoint at Broken.hs:2:23-42 
_result :: [Integer] 
[-1: Broken.hs:2:23-42] *Main> :list 
1 
2 main = print $ head $ filter odd [2, 4, 6] 
3 

Trong thiết bị đầu cuối, biểu thức vi phạm filter odd [2, 4, 6] được tô đậm phông chữ. Vì vậy, đây là biểu thức được đánh giá vào danh sách trống trong trường hợp này.

Để biết thêm thông tin về cách sử dụng trình gỡ lỗi GHCi, hãy xem the GHC User's Guide.

+0

Rực rỡ. Tôi đã không tìm kiếm thông tin về trình gỡ rối GHCi, nhưng điều này thực sự tuyệt vời. –

+0

https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci-debugger.html –

+2

-ngoại trừ-ngoại lệ đã thay đổi thành -fbreak-on-error. – holdenlee

9

Bạn có thể muốn xem Haskell Wiki - Debugging, trong đó có nhiều cách tiếp cận hữu ích cho sự cố của bạn.

Một công cụ hứa hẹn là LocH, trong đó sẽ có thể giúp bạn xác định vị trí head gọi trong mã của bạn đã kích hoạt các danh sách trống lỗi.

Cá nhân, tôi khuyên bạn nên safe gói, cho phép chú thích nhất phần chức năng từ Prelude (và do đó dẫn đến việc sử dụng có ý thức hơn về những chức năng một phần) hoặc tốt hơn, sử dụng tổng biến thể của chức năng chẳng hạn như head luôn trả về kết quả (nếu giá trị đầu vào là được xác định ít nhất là).

+3

Trước tiên, tôi khuyên bạn không nên sử dụng 'head', đặc biệt là đối với người mới sử dụng ngôn ngữ. –

+0

@camccann Tôi hoàn toàn đồng ý ... alas hầu hết các tài liệu giới thiệu tôi đã nhìn thấy (bao gồm cả LYAH khá hiện đại) bắt đầu với giải thích 'đầu' và chỉ cảnh báo về việc cẩn thận không áp dụng nó vào danh sách trống ...: -/ – hvr

+0

Nếu tôi có * cách * của tôi, tôi sẽ xóa nó (cùng với 'đuôi',' (!!) ', và một số thứ khác) từ' Prelude' hoàn toàn và không bao giờ nhắc đến nó cho người mới bắt đầu. Nhưng tốt thôi. –

Các vấn đề liên quan