我完成了(好吧,几乎)我在Haskell中的第一个或多或少有用的项目。它由几个模块组成,几乎所有模块都使用StateT
。
大图是:在顶级我需要同时使用状态和IO,所以我使用StateT myState IO
monad变换器。没关系,我的代码神奇地“只是工作”,但现在我认为代码可能并不完美,因为其他模块中的很多函数都在monad变换器内,所以它们可能会执行IO,尽管它们本质上非常纯粹。这是一件坏事。
你能告诉我如何重构程序,以便我能以某种方式在State
monad中的模块中编写函数,而不需要任何IO
,但是能够将这些代码与顶层的IO结合起来?
答案 0 :(得分:4)
如果您的函数只需要StateT,您可以给它一个签名,例如
incrementCounter :: (Monad m) => (StateT Counter m ())
incrementCounter = do count <- get
put (increment count)
return ()
这样你的函数就需要使用任何Monad m(并且不能依赖它是IO)。在顶层,您可以实例化m = IO。