2011-05-11 39 views
8

Giả sử tôi có một biểu hiện Haskell như:Haskell mô hình phù hợp với trường hợp đối xứng

foo (Nothing, Just a) = bar a 
foo (Just a, Nothing) = bar a 

Có bất kỳ cú pháp Haskell sụp đổ những trường hợp đó, vì vậy tôi có thể phù hợp với một trong hai mô hình và chỉ định bar a như đáp ứng cho cả hai? Hay là ngắn gọn như tôi có thể nhận được nó?

+0

Xem thêm http://stackoverflow.com/questions/5914965/patterns-for-symmetric-functions – kennytm

Trả lời

5

Đó là gọn gàng như trong Haskell. Trong ML có một cú pháp cho những gì bạn muốn (bằng cách viết nhiều mẫu, liên kết các biến tương tự, bên cạnh nhau, cách nhau bởi | với phần thân sau mẫu cuối cùng), nhưng trong Haskell thì không.

8

Nếu mã của bạn phức tạp hơn ví dụ của bạn, bạn có thể muốn làm điều gì đó như thế này, sử dụng ví dụ Alternative cho Maybe và tiện ích mở rộng PatternGuards (một phần của Haskell2010).

{-# LANGUAGE PatternGuards #-} 
import Control.Applicative 

foo (x, y) | Just a <- y <|> x = bar a 

Trong trường hợp bạn không quen thuộc với nó, <|> nhặt trái nhất Just nếu có một và trả Nothing khác, làm cho bảo vệ mô hình thất bại.

+2

một caveat quan trọng mặc dù - này phù hợp với nhiều trường hợp so với bản gốc mã. foo (Chỉ cần x, Just y) sẽ được so khớp, vì vậy nếu đó không phải là những gì bạn muốn, bạn phải chắc chắn để xử lý nó trong một trường hợp trước đó. – mokus

4

Bạn có thể sử dụng -XViewPatterns, để thêm các chức năng tùy ý để thu gọn hai trường hợp của bạn thành một mẫu duy nhất. mô hình của bạn bây giờ là một chức năng p rằng sản lượng điều bạn muốn kết hợp:

foo (p -> (Just a, Nothing)) = bar a 

đơn giản hơn nhiều!

Chúng ta phải xác định p mặc dù, như:

p (Nothing, [email protected](Just _)) = (a, Nothing) 
p [email protected](Just _, Nothing) = a 
p a      = a 

hay tuy nhiên bạn muốn bình thường hóa dữ liệu trước khi xem.


Tài liệu tham khảo: Các GHC User's Guide chapter on View Patterns

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