我需要一个全局计数器,从0、1、2、3等开始。
我有点理解,这个“不纯正”的代码应该单独实现...我才刚刚开始理解Monad,但不知道如何使用Monad来实现这个全局计数器?这对于了解是否有可能是非常有用的示例

最佳答案

State monad提供状态,但仅在monad内部。在函数的重复调用中,它不是持久的。

如果您想要真正的全局,可变状态,则可能需要执行以下操作:

  import Data.IORef

  type Counter = Int -> IO Int

  makeCounter :: IO Counter
  makeCounter = do
      r <- newIORef 0
      return (\i -> do modifyIORef r (+i)
                       readIORef r)

  testCounter :: Counter -> IO ()
  testCounter counter = do
      b <- counter 1
      c <- counter 1
      d <- counter 1
      print [b,c,d]

  main = do
      counter <- makeCounter
      testCounter counter
      testCounter counter

在这里,“makeCounter”创建了一个全局的可变变量,该变量在调用中保持其状态并破坏了纯度。例如,在主函数中,对“testCounter”的两个相同调用给出了不同的结果。
> main
[1,2,3]
[4,5,6]

10-08 12:49