2010-05-17 31 views
130

Tôi đang cố gắng để xác định bất kỳ chức năng đơn giản mà kéo dài nhiều dòng trong ghci, đi sau là một ví dụ:Cách xác định hàm trong ghci trên nhiều dòng?

let abs n | n >= 0 = n 
      | otherwise = -n 

Cho đến nay tôi đã cố gắng nhấn Enter sau khi dòng đầu tiên:

Prelude> let abs n | n >= 0 = n 
Prelude>   | otherwise = -n 
<interactive>:1:0: parse error on input `|' 

tôi cũng đã cố gắng sử dụng các :{:} lệnh nhưng tôi không nhận được đến nay:

Prelude> :{ 
unknown command ':{' 
use :? for help. 

tôi đang sử dụng G HC Interactive phiên bản 6.6 cho Haskell 98 trên Linux, tôi đang thiếu gì?

+19

Vui lòng nâng cấp cài đặt GHC của bạn. GHC 6.6 đã gần 5 tuổi! Các phiên bản mới nhất của Haskell có tại đây: http://haskell.org/platform –

+0

bản sao có thể có của [Lệnh nhiều dòng trong GHCi] (http://stackoverflow.com/questions/8443035/multi-line-commands-in- ghci) – Mark

+0

@Mark OP này đã thử các giải pháp cho vấn đề đó. Vấn đề này là do lỗi thời, không thiếu hiểu biết phải làm gì. Giải pháp ở đây: nâng cấp. Giải pháp ở đó: sử dụng ': {', ':}'. – AndrewC

Trả lời

112

cho bảo vệ (như ví dụ của bạn), bạn chỉ có thể đặt chúng trên cùng một dòng và nó hoạt động (bảo vệ không quan tâm đến khoảng cách)

let abs n | n >= 0 = n | otherwise = -n 

nếu bạn muốn viết chức năng của bạn với nhiều định nghĩa rằng mô hình phù hợp trên các đối số, như thế này:

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

sau đó bạn sẽ sử dụng dấu ngoặc với dấu chấm phẩy tách các định nghĩa

let { fact 0 = 1 ; fact n = n * fact (n-1) } 
7

Nếu bạn không muốn nâng cấp GHC chỉ cho :{:}, bạn sẽ cần phải viết nó trên cùng một dòng:

> let abs' n | n >= 0 = n | otherwise = -n 

tôi m không biết bất kỳ định nghĩa đơn nào trong Haskell rằng phải được viết trên nhiều dòng. Ở trên không thực sự làm việc trong GHCi:

> :t abs' 
abs' :: (Num a, Ord a) => a -> a 

Đối với biểu thức khác, chẳng hạn như do khối, bạn sẽ cần phải sử dụng cú pháp không bố trí với dấu ngoặc nhọn và dấu chấm phẩy (eugh).

43

Dan là đúng, nhưng :{:} từng phải xuất hiện trên một dòng riêng của họ:

> :{ 
> let foo a b = a + 
>   b 
> :} 
> :t foo 
foo :: (Num a) => a -> a -> a 

này cũng tương tác với các nguyên tắc bố trí, vì vậy khi sử dụng làm-ký hiệu nó có thể được dễ dàng hơn để sử dụng niềng răng và bán dấu hai chấm một cách rõ ràng. Ví dụ, định nghĩa này không thành công:

> :{ 
| let prRev = do 
| inp <- getLine 
| putStrLn $ reverse inp 
| :} 
<interactive>:1:18: 
    The last statement in a 'do' construct must be an expression 

Nhưng nó hoạt động khi niềng răng và dấu chấm phẩy được thêm vào:

> :{ 
| let prRev = do { 
| inp <- getLine; 
| putStrLn $ reverse inp; 
| } 
| :} 
> :t prRev 
prRev :: IO() 

này sẽ chỉ thực sự quan trọng khi dán định nghĩa từ một tập tin, nơi thụt đầu dòng có thể thay đổi.

+0

Điều này không hoạt động nếu bạn có dòng kết thúc bằng '=' (với định nghĩa sau trên dòng tiếp theo), ít nhất là trong phiên bản 7.6.3. – AdamC

+0

Có lẽ điều này không thành công, bởi vì dòng thứ hai và thứ ba của lệnh không được thụt vào đủ ...? (Thêm hai dấu cách.) – Evi1M4chine

195

GHCi hiện có chế độ nhập nhiều dòng, được bật với: set + m.Ví dụ:

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

Đặt chế độ đa cấp làm cho 'ghci' hoạt động giống như trình thông dịch Python trong vấn đề này. Rât thuận tiện! Thực tế bạn có thể tạo một tệp '.ghci' trong thư mục chính của bạn, trong đó bạn đặt': set + m' và chế độ nhiều dòng sẽ trở thành mặc định mỗi khi bạn bắt đầu 'ghci'! – kqr

+2

Điều này thực sự tuyệt vời. Nhưng tôi đã nhận thấy rằng khi tôi đặt lời nhắc của tôi bằng cách sử dụng dấu nhắc ': set" λ "' các dòng tiếp tục nói 'Prelude' thay vì' λ'. Còn đường nào để vòng lại chỗ đó không? – abhillman

+2

Xem tại đây để biết bản vá để xác định lời nhắc tiếp tục mới https://ghc.haskell.org/trac/ghc/ticket/7509#no1 – karakfa

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