简体   繁体   English

处理Either和ST monads

[英]Handling Either and ST monads

Let's say I have the following functions: 假设我有以下功能:

checkA :: a -> Either err b
checkA = undefined

checkB :: b -> ST s (Either err c)
checkB = undefined

check :: a -> ST s (Either err c)
check a = either (return . Left) checkB (checkA a)

Is there any way to write check such that it doesn't require using return . Left 有没有办法写check ,这样就不需要使用return . Left return . Left ? return . Left Usually I'd do something like >>= , but in this case the return of checkB is wrapped inside another state monad, so it doesn't work. 通常我会做类似>>=事情,但在这种情况下, checkB的返回包含在另一个状态monad中,所以它不起作用。 The other constraint is that checkB should only run if checkA a evaluates to Right , and should just fail with the error on Left 另一个约束是checkB应该仅在checkA a求值为Right ,并且应该在Left出现错误时失败

To generalize, are there any standard approaches to using nested monads? 总结一下,有没有使用嵌套monad的标准方法?

Here's one way to do it with ExceptT : 以下是使用ExceptT此操作的一种方法:

checkA :: a -> Either err b
checkA = undefined

checkB :: b -> ExceptT err (ST s) c
checkB = undefined

check :: a -> ExceptT err (ST s) c
check a = except (checkA a) >>= checkB
-- or
check = except . checkA >=> checkB

except turns Either err b into Monad m => ExceptT err mb , and then you can do everything else in the ExceptT err (ST s) monad. except转弯Either err b进入Monad m => ExceptT err mb ,然后你可以在ExceptT err (ST s) monad中做其他事情。

As a general rule, ExceptT is a great way to work with monadic actions that may fail when you usually want to bail on failure. 作为一般规则, ExceptT是处理ExceptT的好方法,当您通常想要在失败时保释时可能会失败。 The main exception is when the underlying monad is IO , in which case it's more common to use the built-in exception features from Control.Exception . 主要的例外是底层monad是IO ,在这种情况下,使用Control.Exception的内置异常功能更为常见。

Of course, if you only need one monadic bind, ExceptT seems a bit like overkill, but once you need more it definitely makes sense. 当然,如果你只需要一个 ExceptT绑定, ExceptT看起来有点像矫枉过正,但是一旦你需要更多它肯定是有道理的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM