2017-01-22 19 views
5

Làm cách nào để chuyển đổi StateT g (Either E) T thành ExceptT E (StateT g Identity) T?Hoán đổi các đơn vị trong và ngoài

Có thể, một số kết hợp của traversehoist có thể hữu ích ở đây.

+2

Khi 'StateT g (either e) t' không thành công, nó không cung cấp bất kỳ trạng thái nào. Điều gì sẽ tương ứng 'Ngoại trừ e (StateT g Identity) t' làm gì? – danidiaz

+0

Tôi không thể nhớ lại các định nghĩa chính xác, nhưng không thể đơn nguyên đầu tiên bị lỗi tùy thuộc vào trạng thái (ví dụ: nếu trạng thái là số chẵn), khi trạng thái thứ hai có thể không? – chi

Trả lời

9

You can't exchange an arbitrary pair of monads. Nhưng bạn có thể trao đổi hai monads đặc biệt này. Nó dễ hiểu nhất nếu bạn mở rộng newtype s trong định nghĩa của những biến thế đơn nguyên đó.

Với

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

newtype ExceptT e m a = ExceptT { runExceptT :: m (Either e a) } 

mở rộng newtype s trong biểu loại đầu tiên của bạn cung cấp cho chúng tôi các đẳng cấu

StateT s (Either e) a <-> s -> Either e (s, a) 

trong khi cho phần thứ hai chúng tôi nhận

ExceptT e (StateT s Identity) a <-> s -> (s, Either e a) 

Lưu ý rằng Either e (s, a) có thể hoặc không được chứa s, trong khi (s, Either e a) luôn như vậy. Bây giờ, người ta có thể đi từ cái thứ hai đến cái trước chỉ bằng cách traverse nhập tuple vào bên trong hàm, nhưng đi theo cách khác yêu cầu một số lý do miền cụ thể: nếu tính toán ném một lỗi thì chúng ta nên plumb state thông qua không thay đổi cho catcher lỗi. (Đây có phải là điều đúng đắn để làm không? Tôi thấy điều đó khá đáng tranh cãi.)

stateTEitherToExceptTState :: (s -> Either e (s, a)) -> (s -> (s, Either e a)) 
stateTEitherToExceptTState f s = 
    case f s of 
     Left e -> (s, Left e) 
     Right sa -> fmap Right sa 
+1

Tôi nghĩ 'stateTEitherToExceptTState' không phải là hình thái đơn thuần hợp lệ. Nếu 'm' là một hành động không thất bại, và' f' một mũi tên Kleisli luôn luôn thất bại, 'morph (m >> = f)' không bằng 'morph m> = morph. f'. – danidiaz

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