2015-10-05 18 views
10

Trong Haskell, nếu tôi có một danh sách các công đoàn gõ giá trị như thế này:Làm thế nào để mô hình phù hợp về nhà xây dựng công đoàn trong `cho .. in`

example :: [Either Int Char] 
example = [Left 3, Right 'b', Left 6, Left 9, Right 'c'] 

tôi có thể sử dụng một chút "lừa" để trích xuất tất cả kết quả phù hợp với một số mô hình cụ thể:

lefts :: [Int] 
lefts = [l | Left l <- example] 

Tuy nhiên, nếu tôi cố gắng dịch này để F #, tôi nhận được một lỗi:

let lefts = [for Choice1Of2 l in example -> l] 
       ~~~~~~~~~~~~ 
Incomplete pattern matches on this expression. (...) 

này làm cho rất nhiều ý nghĩa (nó thậm chí có thể là hành vi tốt hơn âm thầm bỏ qua các giá trị Right như Haskell!), nhưng trong F #, có một số cách thuận tiện để trích xuất (và khớp) tất cả các giá trị khớp với một mẫu nhất định trong danh sách/trình tự?

Trả lời

16

Trong F # nếu bạn không khớp với tất cả các trường hợp, bạn sẽ nhận được cảnh báo, trong mọi tình huống.

Vì vậy, bạn có thể viết phù hợp với cả hai trường hợp bên trong biểu hiện, nhưng ví dụ của bạn chứ không phải là comprehensions tôi sẽ sử dụng chức năng List.choose:

let example = [Choice2Of2 3; Choice1Of2 'b'; Choice2Of2 6; Choice2Of2 9; Choice1Of2 'c'] 
List.choose (function (Choice1Of2 x) -> Some x | _ -> None) example 
// val it : char list = ['b'; 'c'] 

Chức năng này rất thuận tiện cho những trường hợp này.

12

Tôi nghĩ rằng điều gần gũi nhất bạn có thể làm bằng biểu thức F # danh sách là một cái gì đó như thế này:

let lefts example = 
    [ for e in example do 
     match e with Choice1Of2 l -> yield l | _ ->() ] 

Nếu tôi hiểu mã Haskell một cách chính xác, phần sau | được sử dụng không chỉ như một vắt, mà còn làm bộ lọc - bỏ qua hoàn toàn tất cả những thứ không khớp với mẫu.

F # không có cùng loại khái niệm trong biểu thức danh sách, do đó bạn phải tiết lộ chi tiết hơn. Ở đây, chúng tôi chỉ lặp qua tất cả các mục bằng cách sử dụng for và sau đó chúng tôi sử dụng một cách rõ ràng yield để tạo một giá trị mới cho mỗi Choice1Of2 trong danh sách nguồn (và chúng tôi chỉ bỏ qua bất kỳ thứ gì khác).

Tùy thuộc vào những gì bạn đang làm, sử dụng List.choose (như đã đề cập trong câu trả lời của Gustavo) có thể dễ dàng hơn. Nhưng ở trên có lẽ là gần nhất bạn có thể nhận được cú pháp hiểu của Haskell.

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