如何使用Monad实现全局计数器? [英] How to implement a global counter using Monad?

查看:109
本文介绍了如何使用Monad实现全局计数器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个全局计数器,从0,1,2,3,.....
开始我明白这个不纯的代码应该分开执行......我刚刚开始了解Monad,但不知道如何使用Monad来实现这个全局计数器?这可能是理解它是否可能的非常有用的例子。

解释方案

状态monad给你状态,但只在monad中。它不会在重复调用函数时持续存在。



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

  import Data.IORef 

type Counter = Int - > IO Int
$ b $ 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'的两个相同的调用给出不同的结果。

 >主
[1,2,3]
[4,5,6]


I need a global counter, starting from 0, 1, 2, 3, ..... I kind of understand that this "impure" code should be separately implemented... I am just starting to understand Monad, but have no idea how to implement this global counter using Monad? This could be very useful example for understanding if it is possible

解决方案

State monad gives you state but only inside the monad. It is not persistent across repeated invocations of the function.

If you want truly global, mutable state you might want to do something like:

  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

Here 'makeCounter' creates a global, mutable variable that is keeps its state across invocations and destroys purity. For example, in the main function two identical calls to 'testCounter' gives different results.

> main
[1,2,3]
[4,5,6]

这篇关于如何使用Monad实现全局计数器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆