如何编写一个可以进行错误处理的状态单子?
我需要编写一个也可以支持错误处理的状态单子。我正在考虑使用 Either monad 来实现此目的,因为它还可以提供有关导致错误的原因的详细信息。我使用 Maybe monad 找到了状态 monad 的定义,但是我无法修改它以使用 Either,而不是 Maybe。这是代码:
newtype StateMonad a = StateMonad (State -> Maybe (a, State))
instance Monad StateMonad where
(StateMonad p) >>= k = StateMonad (\s0 -> case p s0 of
Just (val, s1) -> let (StateMonad q) = k val in q s1
Nothing -> Nothing)
return a = StateMonad (\s -> Just (a,s))
data State = State
{ log :: String
, a :: Int}
I need to write a state monad that can also support error handling. I was thinking of using the Either monad for this purpose because it can also provide details about what caused the error. I found a definition for a state monad using the Maybe monad however I am unable to modify it to use Either, instead of Maybe. Here's the code:
newtype StateMonad a = StateMonad (State -> Maybe (a, State))
instance Monad StateMonad where
(StateMonad p) >>= k = StateMonad (\s0 -> case p s0 of
Just (val, s1) -> let (StateMonad q) = k val in q s1
Nothing -> Nothing)
return a = StateMonad (\s -> Just (a,s))
data State = State
{ log :: String
, a :: Int}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
考虑使用
Control.Monad.Trans.Except
中的ExceptT
(而不是使用 Either)。如果您对 Monad 和 Monad 转换器感到不舒服,那么我会先这样做!它们对程序员的生产力和性能提升有巨大的帮助。
Consider using
ExceptT
fromControl.Monad.Trans.Except
(instead of using Either).If you aren't comfortable with Monads and Monad transformers then I'd do that first! They are a huge help and programmer productivity performance win.
有两种可能的解决方案。与您上面提供的代码最接近的一个是:
另一种形式将错误处理移至状态处理中:
There are two possible solutions. The one that is closest to the code you provided above is:
The other form moves the error handling within the state handling:
你需要一个 monad 转换器。 Monad 转换器库,例如 mtl 允许您组合不同的 monad 来制作新版本。使用 mtl,您可以定义
允许您访问
StateMonad
中的状态和错误处理。You need a monad transformer. Monad transformer libraries such as mtl allow you to compose different monads to make a new version. Using mtl, you could define
which will allow you to access both state and error handling within your
StateMonad
.我没有看到这里有人提到这篇论文 Monad Transformers Step by Step by Martin Grabmüller
我发现它对于学习组合 monad 非常有帮助。
I didn't see anyone here mention the paper Monad Transformers Step by Step by Martin Grabmüller
I found it to be very helpful in learning about combining monads.
的例子
刚刚看到了像and 之类
,但据我了解,如果出现错误,您将丢失状态,因为在这里您在 Either/Except 中添加状态,因此状态只能在 Right 中访问。
如果您需要处理错误并获取状态(截至错误发生时刻计算的状态),您可以使用 ExceptT e (State s) 堆栈:
Just saw examples like
and
but as far as I understand, you will lose your state in case of error, because here you add state inside Either/Except, so state will be only accessible in Right.
If you need handle error and get state, which was computed up to moment where error occurred, you can use ExceptT e (State s) a stack:
您始终可以使用内部带有 State monad 的 ErrorT monad 转换器(反之亦然)。
查看所有关于 monad 的转换器部分。
哈特哈,
You can always use a ErrorT monad transformer with a State monad inside (or vice versa).
Have a look at the transformers section of all about monads.
HTH,