2011-10-06 40 views
15

thể trùng lặp:
Haskell: some and many
Haskell - What is Control.Applicative.Alternative good for?Chức năng từ 'thay thế' kiểu lớp

chức năng somemany trong lớp Alternative loại là gì hữu ích cho? Docs cung cấp định nghĩa đệ quy mà tôi không thể hiểu được.

+0

@Landei: Tôi đã đọc câu trả lời trong chuỗi đó và tôi vẫn chưa hiểu. – missingfaktor

+0

Tôi chỉ nói câu hỏi này là một bản sao, không phải là bản gốc đã có một câu trả lời tốt :-) Mặc dù nó là đủ tốt cho tôi: Tôi đã tìm ra rằng các chức năng này rất có thể không thú vị cho tôi ... – Landei

+0

@Landei: Tôi đang đạt được kết luận tương tự như bạn đã làm. :-) – missingfaktor

Trả lời

33

somemany có thể được định nghĩa là:

some f = (:) <$> f <*> many f 
many f = some f <|> pure [] 

Có lẽ nó giúp để xem cách some sẽ được viết với monadic do cú pháp:

some f = do 
    x <- f 
    xs <- many f 
    return (x:xs) 

Vì vậy some f chạy f một lần, sau đó "nhiều "thời gian và chấp nhận kết quả. many f chạy f "một số" lần hoặc "cách khác" chỉ trả về danh sách trống. Ý tưởng là cả hai đều chạy f càng thường xuyên càng tốt cho đến khi nó "thất bại", thu thập các kết quả trong một danh sách. Sự khác biệt là some f không thành công nếu f không thành công ngay lập tức, trong khi many f sẽ thành công và "trả lại" danh sách trống. Nhưng điều này tất cả có nghĩa là chính xác phụ thuộc vào cách <|> được xác định.

Chỉ hữu ích khi phân tích cú pháp? Hãy xem những gì nó làm cho các trường hợp trong cơ sở: Maybe, []STM.

Đầu tiên Maybe. Nothing có nghĩa là không thành công, do đó, some Nothing không thành công và đánh giá thành Nothing trong khi many Nothing thành công và đánh giá thành Just []. Cả hai some (Just())many (Just()) không bao giờ trở lại, bởi vì Just() không bao giờ bị lỗi! Theo nghĩa nào đó, họ đánh giá là Just (repeat()).

Đối với danh sách, [] nghĩa thất bại, vì vậy some [] đánh giá để [] (không trả lời) trong khi many [] đánh giá để [[]] (có một câu trả lời và nó là danh sách trống). Một lần nữa some [()]many [()] không trả lại. Mở rộng các cá thể, some [()] có nghĩa là fmap (():) (many [()])many [()] có nghĩa là some [()] ++ [[]], vì vậy bạn có thể nói rằng many [()] giống với tails (repeat()).

Đối với STM, lỗi có nghĩa là giao dịch phải được thử lại. Vì vậy, some retry sẽ tự thử lại, trong khi many retry sẽ đơn giản trả về danh sách trống. some fmany f sẽ chạy liên tục f cho đến khi thử lại. Tôi không chắc đây có phải là điều hữu ích hay không, nhưng tôi đoán là không phải vậy.

Vì vậy, đối với Maybe, []STMmanysome dường như không hữu ích.Nó chỉ hữu ích nếu ứng dụng có một số loại trạng thái mà làm cho thất bại ngày càng có khả năng khi chạy cùng một điều hơn và hơn. Đối với các trình phân tích cú pháp, đây là đầu vào được thu hẹp lại với mọi kết quả thành công.

8

Ví dụ: cho parsing (xem phần "Phân tích cú pháp bằng ví dụ").

+2

Tôi không quen thuộc với Parsec. Tôi đánh giá cao một số lời giải thích. – missingfaktor

+2

Theo tôi hiểu, nếu bạn có trình phân tích cú pháp 'p' cho X, thì' một số p' là một trình phân tích cú pháp cho 0 hoặc nhiều X và 'nhiều p' là một trình phân tích cú pháp cho 1 hoặc nhiều X. – Ingo

+2

@missingfaktor' một số 'và' nhiều' được triển khai theo '<|> '. Bộ kết hợp này cũng hữu ích theo những cách khác. Xem xét 'Cả hai': 'ChỉChỉ 1 = Chỉ 0',' Không có gì <|> Chỉ 2 = Chỉ 2', 'Chỉ cần 3 <|> Không có gì = Chỉ 3',' Không có gì <|> Không có gì = Nothing' – fuz

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