Những gì đơn nguyên là trái ngược với các đơn vị lỗi trong haskell


9

Trong đơn vị lỗi, lỗi đầu tiên tạm dừng bất kỳ thực thi nào nữa chỉ mang lỗi thông qua bất kỳ ràng buộc nào sau đây.

Điều gì đơn vị dừng lại ở thành công chỉ mang lại thành công về phía trước, và về cơ bản nuốt bất kỳ lỗi nào và cố gắng ràng buộc tiếp theo bất chấp sự thất bại của lần trước?

Đơn vị lỗi có thể được sử dụng cho việc xử lý thất bại này như thành công, nhưng tôi tò mò liệu các thư viện mặc định có một đơn vị cho mục đích cụ thể này, gần giống như một đơn vị Or trong tâm trí của tôi "Làm điều này hoặc điều đó"

Biên tập:

Hành vi sẽ là:

Left "fail" >>= (\x -> Right "win") >>= (\x -> Left "ahh neener") >>= (\x -> Right (x + " yay"))

Trong lỗi đơn nguyên, giá trị bên trái đầu tiên chỉ được chuyển tiếp, vì vậy kết quả của điều đó là Left "fail". Hành vi tôi muốn là ở trên, Right "win yay"đó là một đơn vị tầm thường để thực hiện tôi có thể tự viết, nhưng đã tìm ra thứ gì đó tồn tại để làm như vậy (có thể không sử dụng Either, nhưng đó là điều đầu tiên xuất hiện trong hành vi đó).


Tại sao các downvote? Có điều gì xấu về câu hỏi này?
Jimmy Hoffa

Bạn có thể cung cấp một đoạn mã nhỏ để thể hiện suy nghĩ của bạn không?
Daniel Gratzer

Có thể là bạn đang nghĩ về việc quay lại?
Scarfridge

Câu trả lời:


4

Những gì bạn cần là MonadPlus (xem thêm wiki Haskell ). Nó định nghĩa

mzero :: m a

đại diện cho một lỗi không xác định và

mplus :: m a -> m a -> m a

trong đó cố gắng tính toán thứ hai, nếu lần đầu tiên thất bại. Một vài chức năng phụ trợ cũng được cung cấp:

-- Extends `mplus` to lists of computations:
msum :: MonadPlus m => [m a] -> m a
-- Fails a computation conditionally.
guard :: MonadPlus m => Bool -> m ()
-- Filter (fail) computations that don't satisfy the predicate.
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

Trường hợp MonadPluscó thể được chia thành hai loại:

  1. mpluskết hợp tất cả các kết quả có thể có từ cả hai đối số của nó (thỏa mãn luật Phân phối còn lại). []Seqcó lẽ là trường hợp duy nhất với hành vi này.
  2. mpluschọn đối số bên trái, nếu nó chứa giá trị hợp lệ, nếu không, nó sẽ chọn đối số bên phải (thỏa mãn luật Bắt trái). Trường hợp có hành vi này là Maybe, Either, STMIO.

( MonadPlusví dụ Eitherđược sử dụng để được định nghĩa trong Control.Monad.Error là

instance (Error e) => MonadPlus (Either e) where
    mzero            = Left noMsg
    Left _ `mplus` n = n
    m      `mplus` _ = m

nhưng vì một số lý do, nó dường như bị thiếu trong phiên bản hiện tại.)

Xem thêm MonadPlus trên định nghĩa WikibooksMonadPlus cho Haskell IO .


Cảm ơn, âm thanh như danh sách monadplus là suy nghĩ tôi đã có.
Jimmy Hoffa

@JimmyHoffa Tôi quên đề cập đến đó Seqcũng là một ví dụ MonadPlus. Tôi thực sự muốn giới thiệu nó [], bởi vì ghép ( mplus) cho SeqO (log n) trong khi nối các danh sách là O (n) .
Petr Pudlák

Wiki haskell rất sáng sủa, nghe có vẻ như cộng đồng haskell đang cân nhắc xem nó nên đi theo cách nào giống như tôi đang suy nghĩ xem tôi muốn nó hoạt động theo cách nào; dù tôi muốn nó là Hoặc là "Cái này hay cái kia" hay "Cái này thì cái kia" khi cái đầu tiên thất bại gây ra hành vi như Hoặc sử dụng giá trị trước thất bại cho cái tiếp theo, nhưng thành công vẫn gọi tiếp theo không giống như Or và sử dụng giá trị được trả về từ hàm đầu tiên.
Jimmy Hoffa

Vâng, tôi ủng hộ đề xuất cải cách MonadPlus , tôi tin rằng điều này sẽ làm rõ mọi thứ rất nhiều.
Petr Pudlák
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.