2011-09-16 34 views
5

Tôi mới sử dụng Haskell. Tôi đã viết đơn nguyên của riêng mình là đơn vị nhà nước có xử lý lỗi:Làm thế nào để thêm IO vào monad của riêng tôi trong Haskell?

newtype MyMonad a = MyMonad (State -> Either MyError (State, a)) 

Tôi sử dụng nó bằng thông dịch viên của một ngôn ngữ nhỏ. Bây giờ tôi muốn thêm một số hoạt động IO vào ngôn ngữ của tôi (đọc/ghi), nhưng tôi không biết làm thế nào để kèm theo IO monad bên trong của tôi. Tôi biết tôi có thể kết hợp ErrorT, StateT, IO và đạt được kết quả này nhưng có cách nào khác để làm điều đó mà không có chúng?

Trả lời

6

Bạn có thể xem xét cách StateT được thực hiện:

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) } 

Để kết hợp nhà nước với IO bạn chỉ cần đặt IO ở vị trí của m và nhận được kiểu như mong muốn: s -> IO (a,s).

Nếu bạn có lỗi quá, điều này sẽ trở thành một cái gì đó như s -> IO (Either e (a, s)) hoặc s -> IO (Either e a, s) tùy thuộc vào việc bạn muốn tính toán thất bại có ảnh hưởng đến trạng thái hay không.

Lưu ý rằng bạn không thể tạo s -> Either e (IO (a, s)) một đơn vị mà không có máy thời gian .

Cập nhật

Hóa ra bạn không thể làm cho nó một đơn nguyên ngay cả với cỗ máy thời gian.

Để hiển thị tại sao nó là không thể, chúng ta hãy đơn giản hóa đơn nguyên của chúng tôi bằng cách sử dụng () thay vì s đầu tiên: data M e a = M { runM :: Either e (IO a) }

Bây giờ, hãy tưởng tượng chương trình sau đây:

unsafePerformIO :: IO a -> a 
unsafePerformIO io = fromLeft $ runM $ do 
    a <- M $ Right $ io 
    M $ Left a 

Rõ ràng, chức năng này là bất khả thi và do đó, ví dụ đơn lẻ cho M cũng không thể thực hiện được.

Máy thời gian nào có thể cung cấp cho bạn là khả năng xử lý IO chính xác như một xử lý State. Tuy nhiên, tôi không nhận ra rằng Either e (s -> (a, s)) không phải là một đơn nguyên.

+0

Máy thời gian? Bạn có thể cung cấp một số ngữ cảnh? Có một số trò đùa "chơi đùa" hay là một số thuật ngữ khoa học toán học/lập trình nâng cao? – Tarrasch

+1

Không có trò chơi chữ nào ở đây, tôi đang nói về một cỗ máy thời gian thực. Một khi bạn có nó, bạn có thể thực hiện đơn nguyên này. – Rotsor

+1

@Rotsor: cẩn thận để giải thích * tại sao * cho biết máy thời gian là bắt buộc? – ivanm

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