Подтвердить что ты не робот

Как реализовать глобальный счетчик с помощью Monad?

Мне нужен глобальный счетчик, начиная с 0, 1, 2, 3,..... Я понимаю, что этот "нечистый" код должен быть реализован отдельно... Я только начинаю понимать Monad, но понятия не имею, как реализовать этот глобальный счетчик с помощью Monad? Это может быть очень полезным примером для понимания, если это возможно.

4b9b3361

Ответ 1

Государственная монада дает вам состояние, но только внутри монады. Это не является постоянным при повторных вызовах функции.

Если вы хотите действительно глобальное изменчивое состояние, вы можете сделать что-то вроде:

  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]

Ответ 2

Вы можете реализовать это, используя монаду State, которая сохраняет текущее значение вашего счетчика как состояние. Затем вы можете использовать get, чтобы получить текущее значение счетчика, и modify (+1), чтобы увеличить его.

Одним из полезных вариантов этого является монада Supply, где вы можете использовать произвольную последовательность в качестве своего "счетчика", чтобы иметь простой счетчик, начиная с нуль, просто используйте [0..] в качестве источника.

Ответ 3

То, что вы можете посмотреть, это государственная монада. Это общая монада, которая может использоваться для управления состоянием. В вашем случае счетчик - это просто состояние, которое вы хотите сохранить.

http://www.haskell.org/haskellwiki/State_Monad

Ответ 4

В то время как состояние в порядке, вам не нужно проверять счетчик при расчете, но только для его увеличения, поэтому Writer monad должна быть достаточным. См. Узнайте о вас Haskell для (не слишком серьезного) введения.