2012-06-28 59 views
17

Tôi thấy ưu tiên và khả năng kết hợp là một trở ngại lớn đối với tôi để hiểu ngữ pháp đang cố gắng thể hiện ở cái nhìn đầu tiên về mã haskell.Ưu tiên Haskell: Lambda và nhà điều hành

Ví dụ,

blockyPlain :: Monad m => m t -> m t1 -> m (t, t1) 
blockyPlain xs ys = xs >>= \x -> ys >>= \y -> return (x, y) 

Bằng cách thử nghiệm, cuối cùng tôi đã nhận nó có nghĩa là,

blockyPlain xs ys = xs >>= (\x -> (ys >>= (\y -> return (x, y)))) 

thay vì

blockyPlain xs ys = xs >>= (\x -> ys) >>= (\y -> return (x, y)) 

Những công trình như:

*Main> blockyPlain [1,2,3] [4,5,6] 
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)] 

Tôi có thể lấy thông tin từ ghci cho (>> =) làm toán tử, (infixl 1 >> =).

Nhưng không có thông tin cho -> vì đó không phải là toán tử.

Có thể ai đó trong số các bạn đưa ra một số tham chiếu để làm cho điều ngữ pháp này dễ nắm bắt hơn không?

+0

[Haskell Báo cáo] (http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-220003) là tham chiếu chính xác cho cú pháp Haskell, mặc dù có lẽ ngữ pháp BNF hơi thấp đối với câu hỏi mà bạn đang sử dụng hỏi ...? –

Trả lời

23

Quy tắc cho lambdas khá đơn giản: phần thân của lambda mở rộng càng xa càng tốt mà không nhấn dấu ngoặc đơn không cân bằng.

f (\x -> foo (bar baz) *** quux >>= quuxbar) 
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
         body 
+3

Điều đó có nghĩa là nó được áp dụng cuối cùng. Tức là, (->) có ưu tiên thấp hơn bất kỳ toán tử nào khác. Tôi tin điều tương tự cũng đúng với 'do' và (<-) cũng như chúng mở rộng càng xa càng tốt, áp dụng cuối cùng, và có ưu tiên thấp hơn bất kỳ toán tử nào. –

+4

Tôi thực sự không thích các thuật ngữ "đầu tiên" và "cuối cùng" cho quyền ưu tiên - tôi nghĩ rằng nó conflates nhóm với thứ tự đánh giá. Đó là một cái gì đó tôi chạy lên chống lại trong giảng dạy toán học. Tôi thích "chặt chẽ" và "lỏng lẻo", suy nghĩ của các nhà khai thác như tổ chức trên để operands của họ. Dù sao, '->' không thực sự là một toán tử infix, vì nó không kết nối hai từ; thay vào đó, lambda là một dạng cú pháp cho một biểu thức. Đó là lý do tại sao tôi không trả lời về điều hành. – luqui

+1

Cả hai điểm đều được thực hiện tốt. "Đầu tiên" và "cuối cùng" là các cụm từ được sử dụng trong hầu hết các chương trình toán học k-12 (và không phải là một vài lớp) khi nói về thứ tự các hoạt động. Nỗ lực của tôi là áp dụng những thuật ngữ thường được sử dụng (mặc dù ít chính xác hơn) cho câu trả lời rất tốt của bạn. –

7

Một nguyên tắc chung có vẻ là bạn không bao giờ có thể làm toán tử tùy chỉnh được ưu tiên hơn xây dựng trong cấu trúc cú pháp. Ví dụ xem xét ví dụ sau:

if b then f *** x else f *** y 

Bất kể kết hợp của ***, không ai mong chờ nó với phím tắt như:

(if b then f *** x else f) *** y 

Không có rất nhiều cấu trúc cú pháp trong Haskell (docase hơi đặc biệt do cú pháp bố cục) nhưng có thể sử dụng let làm ví dụ khác:

(let x = y in y *** x) /= ((let x = y in y) *** x) 
+2

Ngoại trừ ứng dụng chức năng và cập nhật bản ghi ... – luqui

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