2011-10-26 29 views
5

Vì vậy, tôi có một kiểu dữ liệu kiểu như:Kiểm tra xem Haskell biến phù hợp với lựa chọn kiểu dữ liệu do người dùng định nghĩa

data Token = NUM Int | ID String | EOF 

và tôi có một chức năng loại giống như:

doStuff list = let 
     (token, rest) = getToken list 
    in 
     .... 

Vì vậy, những gì tôi muốn làm trong phần ... là thử nghiệm nếu mã thông báo tôi nhận được là NUM hoặc INT hoặc EOF. Tôi có thể nói token==EOF để kiểm tra trường hợp đó, nhưng tôi không thể tìm ra cách để kiểm tra xem mã thông báo có là NUM hoặc INT sử dụng điều kiện không, vì token==(NUM n)token==NUM cả hai đều dẫn đến lỗi. Tôi biết rằng tôi có thể viết một hàm trợ giúp để thực hiện các công cụ trong ... và tận dụng lợi thế của mẫu phù hợp, nhưng điều đó thực sự làm tổn hại đến khả năng đọc của những gì tôi đang làm, và có vẻ như có một cách để thực hiện việc kiểm tra này. Có ai biết không?

Trả lời

12

Bạn muốn có một case biểu hiện, như:

case token of 
    NUM n -> foo n 
    ID s -> bar s 
    _  -> hoho 

Đó là cùng một loại phù hợp với mô hình như bạn muốn nhận được nếu bạn đã định nghĩa một hàm riêng.

8

Một mẹo dễ thương cho việc này là sử dụng cú pháp ghi. Ưu điểm của phương pháp này là nó tiếp tục làm việc ngay cả khi số lượng đối số cho một hàm tạo cụ thể thay đổi. Lưu ý rằng chính loại dữ liệu không cần khai báo bằng cú pháp ghi để tận dụng lợi thế của thủ thuật này.

case token of 
    NUM {} -> ... 
    ID {} -> ... 
    EOF {} -> ... 
+0

Làm cách nào để bạn có được giá trị? Hình như bạn ném chúng đi đây ... – mergeconflict

+0

@mergeconflict Nếu bạn muốn các giá trị, bạn không sử dụng thủ thuật này, tất nhiên. =) Nhưng nó nghe từ câu hỏi như anh ta chỉ muốn kiểm tra xem constructor nào đã được sử dụng. –

+0

@mergeconflict bạn có thể chọn lọc các vals như thế này: 'dữ liệu Mã thông báo = NUM ​​{n, m :: Int}' --- 'mã thông báo trường hợpVal of Num {n = n '} -> foo n'' –

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