-- | A Cell is a container for a value.  It is created with the value in it.
-- The only change we can make is to remove the value, and we cannot put
-- it back again.
module Events.Cells(
   Cell, -- The Cell type
   newCell, -- :: a -> IO (Cell a)
   emptyCell, -- :: Cell a -> IO ()
      -- emptying an already empty cell does nothing.
   inspectCell, -- :: Cell a -> IO (Maybe a)
      -- returns the value, or Nothing if the Cell has been cleared.
   ) where

import Data.IORef

newtype Cell a = Cell (IORef (Maybe a))

newCell :: a -> IO (Cell a)
newCell :: a -> IO (Cell a)
newCell a
val =
   do
      IORef (Maybe a)
ioRef <- Maybe a -> IO (IORef (Maybe a))
forall a. a -> IO (IORef a)
newIORef (a -> Maybe a
forall a. a -> Maybe a
Just a
val)
      Cell a -> IO (Cell a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IORef (Maybe a) -> Cell a
forall a. IORef (Maybe a) -> Cell a
Cell IORef (Maybe a)
ioRef)

emptyCell :: Cell a -> IO ()
emptyCell :: Cell a -> IO ()
emptyCell (Cell IORef (Maybe a)
ioRef) = IORef (Maybe a) -> Maybe a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe a)
ioRef Maybe a
forall a. Maybe a
Nothing

inspectCell :: Cell a -> IO (Maybe a)
inspectCell :: Cell a -> IO (Maybe a)
inspectCell (Cell IORef (Maybe a)
ioRef) = IORef (Maybe a) -> IO (Maybe a)
forall a. IORef a -> IO a
readIORef IORef (Maybe a)
ioRef

{-# INLINE newCell #-}
{-# INLINE emptyCell #-}
{-# INLINE inspectCell #-}