2012-07-05 38 views
12

Tôi muốn có một chức năng như sau, điều này có khả thi không? trên thực tế, tôi không biết loại Mô hình có tồn tại hay không.Tôi có thể chuyển mẫu vào một chức năng không?

fun1 a :: Pattern a -> a -> Bool 
fun1 pattern a = case a of 
    pattern -> True 
    _ -> False 
+1

tôi không nói F #, nhưng tôi nghĩ [mô hình hoạt động] (http: // msdn.microsoft.com/en-us/library/dd233248.aspx) có thể làm điều tương tự. – phg

Trả lời

13

Tôi không nghĩ rằng điều này có thể xảy ra trong Haskell.

Tuy nhiên, trong trường hợp của bạn, mẫu có hiệu quả chỉ là một chức năng thuộc loại a -> Bool. Vì vậy, thay vì chấp nhận mẫu, hãy chấp nhận bất kỳ chức năng nào từ a đến Bool. Ví dụ của bạn tương đương với việc áp dụng hàm a -> Bool trên a.

Bây giờ, nếu bạn muốn làm điều gì đó tổng quát hơn, giống như việc có thể sử dụng các biểu tượng phù hợp từ mẫu trong phần fun1, bạn sẽ không thể thực hiện nó bằng chức năng. Tuy nhiên, tôi nghi ngờ điều này là có thể với Haskell ở tất cả - nó sẽ yêu cầu phần mở rộng lạ cho hệ thống loại để làm cho bất kỳ ý nghĩa. So khớp mẫu trong Haskell không phải là một công dân hạng nhất, vì vậy bạn không thể thực sự vượt qua các mẫu xung quanh như vậy.

Nếu bạn muốn loại hành vi này, hãy xem sách Pattern Calculus nơi tác giả phát triển và chính thức hóa một ngôn ngữ có nhiều tính năng khớp mẫu tổng quát hơn Haskell. Nó làm cho các mẫu trở thành một công dân hạng nhất, không giống như Haskell. Tôi chưa thực sự hoàn thành cuốn sách này, nhưng tôi khá chắc chắn rằng mã như vậy là chính xác những gì bạn sẽ có thể viết, trong số những thứ khác.

Tác giả đã xây dựng ngôn ngữ xung quanh ý tưởng của mình về kết hợp mẫu được gọi là bondi; nó có lẽ cũng đáng để kiểm tra, đặc biệt là nếu bạn không muốn bận tâm với cuốn sách. Tôi không biết nếu nó đã sẵn sàng để sử dụng thực tế, nhưng nó chắc chắn thú vị.

+0

ghc có phần mở rộng ViewPattern này kể từ phiên bản 6.10 (04-tháng 11 năm 2008). Với phần mở rộng cú pháp đó, những "mẫu" này chỉ là ánh xạ hàm từ giá trị được phân tích đến kết quả tương ứng với mẫu. – comonad

+0

@comonad: Tôi không chắc rằng phần mở rộng ViewPattern có thể áp dụng ở đây hay không - nó cho phép bạn sử dụng các hàm như là các mẫu mà OP muốn sử dụng các mẫu làm hàm. –

+0

Tôi đã đề cập đến phần thứ hai của bạn: "..., giống như việc có thể sử dụng các biểu tượng phù hợp từ mẫu trong phần thân của fun1, bạn sẽ không thể thực hiện nó bằng chức năng." Vâng, bằng cách sử dụng ViewPatterns, chức năng/mẫu đó phải trả lại các kết buộc phù hợp để người gọi có thể liên kết chúng với các biến của riêng mình hoặc với mẫu khớp với chúng hơn nữa. Nếu điều đó quá dài (và nếu tôi nhớ chính xác), có tồn tại một thủ thuật với RecordWildcards cho phép bạn kết hợp các biến có tên cụ thể với một giá trị. – comonad

0

Tôi chắc chắn rằng bạn đang tìm kiếm Xem mẫu.

(xem trac/ghc/wiki hoặc ghc/user-manual/syntax-extensions)


Mỗi chức năng là một "mẫu":

case "string that ends with x" of 
    (last->'x') -> True 
    _ -> False 

case "foo" of 
    (elemIndex 'g'->Just i) -> i+5 
    (elemIndex 'f'->Nothing) -> 23 
    _ -> 42 

do 
    x <- fmap foo bar 
= 
do 
    (foo->x) <- bar 
+1

Tôi nghĩ rằng anh ấy đã yêu cầu điều ngược lại - thay vì sử dụng các chức năng như các mẫu, anh ấy muốn sử dụng các mẫu như các hàm. Vì vậy, anh ta muốn có thể gọi 'fun1 (Just x) a' và khớp với giá trị của' a' so với * pattern * 'Just x'.Đây là những gì thư viện liên kết trong câu trả lời được chấp nhận cho phép bạn làm. Tôi không nghĩ rằng ViewPatterns cho phép bạn làm điều đó mặc dù. –

+0

Tikhon Jelvis: Thú vị, không cân nhắc quan điểm đó. Trên thực tế, Jason đã yêu cầu sử dụng các mẫu làm mẫu. Nhưng để làm cho một chức năng ra khỏi một mô hình là tầm thường. AFAIC Jason mới dùng Stackoverflow và vừa chấp nhận bất kỳ câu trả lời nào mà không bình luận nó; Tôi không chắc chắn rằng anh chỉ muốn có một câu trả lời cụ thể. – comonad

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