如何重构使用状态monad变换器的程序?

时间:2014-10-20 13:49:22

标签: haskell io state monads

我完成了(好吧,几乎)我在Haskell中的第一个或多或少有用的项目。它由几个模块组成,几乎所有模块都使用StateT

大图是:在顶级我需要同时使用状态和IO,所以我使用StateT myState IO monad变换器。没关系,我的代码神奇地“只是工作”,但现在我认为代码可能并不完美,因为其他模块中的很多函数都在monad变换器内,所以它们可能会执行IO,尽管它们本质上非常纯粹。这是一件坏事。

你能告诉我如何重构程序,以便我能以某种方式在State monad中的模块中编写函数,而不需要任何IO,但是能够将这些代码与顶层的IO结合起来?

1 个答案:

答案 0 :(得分:4)

如果您的函数只需要StateT,您可以给它一个签名,例如

incrementCounter :: (Monad m) => (StateT Counter m ())
incrementCounter = do count <- get
                      put (increment count)
                      return ()

这样你的函数就需要使用任何Monad m(并且不能依赖它是IO)。在顶层,您可以实例化m = IO。