【发布时间】:2014-04-17 08:15:44
【问题描述】:
我正在编写一些代码,使用 StateT monad 转换器来跟踪一些状态信息(日志记录等)。
我传递给StateT 的单子非常简单:
data CheckerError a = Bad {errorMessage :: Log} | Good a
deriving (Eq, Show)
instance Monad CheckerError where
return x = Good x
fail msg = Bad msg
(Bad msg) >>= f = Bad msg
(Good x) >>= f = f x
type CheckerMonad a = StateT CheckerState CheckerError a
这只是Left 和Right 的变体。
困扰我的是fail的定义。在我的计算中,我在这个 monad 中产生了很多信息,即使失败,我也想保留这些信息。
目前我唯一能做的就是将所有内容转换为String,并创建一个Bad 实例,并将String 作为参数传递给fail。
我想做的是这样的:
fail msg = do
info <- getInfoOutOfTheComputation
return $ Bad info
但是到目前为止我尝试的所有操作都会出现类型错误,可能是因为这会混合不同的 monad。
无论如何我可以实现fail 以保留我需要的信息,而不必将其全部转换为String?
我不敢相信 Haskell 能达到的最佳效果是使用 show+read 将所有信息作为字符串传递给 fail。
【问题讨论】:
-
简短回答:这不是
fail的用途,所以它当然不起作用。 -
@Carl 然后告诉我我应该如何实现这一点。我想要的是:1)一种在发生不好的事情时“停止”计算的方法 2)保留到目前为止产生的有状态信息。我见过的所有示例都能够实现 1 使用
fail而未能实现数字 2。目前我想出的唯一事情是:prettyFail = do state <- get; fail $ show state在所有状态信息中实现Show和Read,这我认为这不是一个优雅的解决方案(尽管效果很好)。 -
fail仅用作权宜之计,以支持 do-notation 中的模式匹配失败。
标签: haskell monads monad-transformers state-monad