0 | module Data.Ref
 1 |
 2 | import public Data.IORef
 3 | import public Control.Monad.ST
 4 | import Control.Monad.State.Interface
 5 |
 6 | %default total
 7 |
 8 | public export
 9 | interface Monad m => Ref m r | m where
10 |   newRef : {0 a : Type} -> a -> m (r a)
11 |   readRef : {0 a : Type} -> r a -> m a
12 |   writeRef : r a -> a -> m ()
13 |
14 |   ||| Updates a value and returns the previous value
15 |   modifyRef : (a -> a) -> r a -> m a
16 |   modifyRef f ref = do
17 |     old <- readRef ref
18 |     writeRef ref (f old) $> old
19 |
20 | public export
21 | modifyRef_ : Ref m r => (a -> a) -> r a -> m ()
22 | modifyRef_ = ignore .: modifyRef
23 |
24 | export
25 | HasIO io => Ref io IORef where
26 |   newRef = newIORef
27 |   readRef = readIORef
28 |   writeRef = writeIORef
29 |
30 | export
31 | Ref (ST s) (STRef s) where
32 |   newRef = newSTRef
33 |   readRef = readSTRef
34 |   writeRef = writeSTRef
35 |
36 | namespace MonadState
37 |
38 |   export
39 |   ForRef : Ref m r => Monad m => r a -> MonadState a m
40 |   ForRef ref = MS where
41 |     %inline
42 |     [MS] MonadState a m where
43 |       get = readRef ref
44 |       put = writeRef ref
45 |