什么(如果有的话)是最小化 IO Monad 对我的代码的影响的普遍接受的方法

What (if any) is the generally accepted way of minimising the impact of the IO Monad on my code

我在使用 IO Monad 时遇到了一些困难。 (仍然是 101 学习者)

我相信我理解将“IO”与纯功能代码分开的充分理由,但这似乎使我的代码在使用时钟和环境属性时变得更加复杂。这是一个示例(与时钟相关):

timeZoneSeconds = liftA (60*) $ liftA timeZoneMinutes getCurrentTimeZone

现在,在程序的其他地方,我还有很多其他事情要用 timeZoneSeconds 做——加法、减法、比较,并且当 timeZoneSeconds 与其他位交互时,实际上我正在处理的所有事情都变成了“ IO”,从而用 liftAs 填充我的代码。

所以基本上我看到我所有的纯代码都变成了 IO 脏代码。

在我所见的所有说教 material 中,大多数关于 IO monad 的解释都是笼统的“读东西然后写东西”,没有太多“计算东西”。

是否有推荐的方法来尽量减少这种影响?

我是否应该重新定义我需要“在幕后”使用 liftA 的所有运算符?

还是我应该继续做下去?

将其视为依赖注入。您将不纯调用的结果注入您的纯代码,然后使用纯代码的结果进行更多不纯的 IO,例如打印结果:

main = do
  env <- lookupEnv "ENV"
  tz <- getCurrentTimeZone
  let result = pureCode env tz
  putStr result

您的 pureCode 函数没有任何 IO 附加。