haskell - 处理 Either 和 ST monad

标签 haskell monad-transformers state-monad

假设我有以下功能:

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)

有没有办法写check这样就不需要使用 return . Left ?通常我会做类似 >>= 的事情,但在本例中返回 checkB被包裹在另一个状态单子(monad)中,所以它不起作用。另一个约束是checkB应该仅在 checkA a 时运行计算结果为Right ,并且应该会失败并出现 Left 上的错误

概括来说,是否有使用嵌套 monad 的标准方法?

最佳答案

这是使用 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

exceptEither err b 转换为 Monad m => exceptT err m b,然后你就可以在 中执行其他操作exceptT err (ST s) monad。

作为一般规则,ExceptT 是处理单子(monad)操作的好方法,当您通常想要在失败时放弃时,这些操作可能会失败。主要的异常是底层 monad 为 IO 时,在这种情况下,更常见的是使用 Control.Exception 中的内置异常功能。

当然,如果您只需要一个单子(monad)绑定(bind),ExceptT似乎有点大材小用,但一旦您需要更多,它肯定是有意义的。

关于haskell - 处理 Either 和 ST monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55264051/

相关文章:

haskell - 如何创建 MonadRandom (StateT PureMT m0)? ( haskell )

networking - 如何将 Unix POSIX 文件描述符或标准输入句柄转换为套接字?

haskell - 使用通用函数映射异构数据结构

haskell - 为什么我不能编写一个通用函数来检查两个列表是否相等?

haskell - 使用 runReaderT 消除 MonadReader 约束

haskell - 从 State 切换到 StateT 后,如何恢复单子(monad)构造列表的惰性求值?

haskell - 对 "Learn you a Haskell"上的 State Monad 代码感到困惑

haskell - 函数签名如何匹配请求的类型

haskell - 是否/应该将函数包装到 monad 转换器中被视为不好的做法?

haskell - 如何创建一个允许 IO 但不是 MonadIO 的 monad?