MatrixAI / Relay

Service-Centric Networking for Matrix Automatons
0 stars 0 forks source link

Simplify State Monad Counter Code #22

Closed CMCDragonkai closed 5 years ago

CMCDragonkai commented 5 years ago

I think the state counter code is too complicated right now. We can assume that we don't want to reuse numbers yet. We can figure that out later.

To have the same API as the js-resource-counter (https://www.npmjs.com/package/resource-counter), you should be able to make do with something like this:

import Control.Monad.State

-- basic naive way of doing this
-- notice that it's the same type signature as `s -> (a, s)`
allocate :: Int -> (Int, Int)
allocate n = (n, n + 1)

result1 :: IO ()
result1 = do
  let (r1, c1) = allocate 0
  print r1
  let (r2, c2) = allocate c1
  print r2
  let (r3, c3) = allocate c2
  print r3

-- let's try to use StateT transformer
-- with IO monad to interleave the printing action
allocate2 :: StateT Int IO Int
allocate2 = do
  n <- get
  put $ n + 1
  return n

result2 :: StateT Int IO ()
result2 = do
  n <- allocate2
  liftIO $ print n
  n <- allocate2
  liftIO $ print n
  return ()

result2' :: IO ((), Int)
result2' = runStateT result2 0

result2'' :: IO ((), Int)
result2'' = runStateT go 0
  where
    go = do
      n <- allocate2
      liftIO $ print n
      n <- allocate2
      liftIO $ print n
      return ()

-- since `allocate` has the right type signature
-- we can transform into a state monadic action
allocate' :: State Int Int
allocate' = state allocate

-- now we can use it in a state monad
result3 :: State Int ()
result3 = do
  allocate'
  allocate'
  allocate'
  return ()

-- running and priming it with 0
result3' = runState result3 0

-- also see evalStateT and execStateT
CMCDragonkai commented 5 years ago

The reason why using a list as a stack is a bad idea to remember the deallocated numbers is because the list is not ordered naturally, you have to put the number into stack from lowest to highest. The stack thus needs to be a min-heap not a simple list. At any case, if we are going to go for a stack to implement deallocation, we might as well go the full way and implement the resource counter tree directly into Haskell by porting the JS implementation.

CMCDragonkai commented 5 years ago

@ramwan Hey close this if this is now done.

CMCDragonkai commented 5 years ago

@ramwan Hey close this if this is now done.