module Ouroboros.Consensus.Util.MonadSTM.NormalForm (
    module LazySTM
  , module Ouroboros.Consensus.Util.MonadSTM.StrictSVar
  , module StrictSTM
  , newEmptySVar
  , newSVar
    -- * Temporary
  , uncheckedNewEmptySVar
  , uncheckedNewSVar
  ) where

import           Control.Concurrent.Class.MonadSTM.Strict.TMVar as StrictSTM hiding
                     (newTMVar, newTMVarIO, traceTMVar, traceTMVarIO)
import           Control.Concurrent.Class.MonadSTM.TBQueue as LazySTM
import           Control.Concurrent.Class.MonadSTM.TQueue as LazySTM
import           Control.Monad.Class.MonadSTM as StrictSTM hiding (traceTVar,
                     traceTVarIO)
import           GHC.Stack
import           NoThunks.Class (NoThunks (..), unsafeNoThunks)
import           Ouroboros.Consensus.Util.MonadSTM.StrictSVar hiding
                     (newEmptySVar, newEmptySVarWithInvariant, newSVar,
                     newSVarWithInvariant)
import qualified Ouroboros.Consensus.Util.MonadSTM.StrictSVar as Strict

-- TODO: use strict versions of 'TQueue' and 'TBQueue'.  Previously the
-- 'Control.Monad.Class.MonadSTM.Strict' was imported which
-- exported lazy 'TQueue' and 'TBQueue',  I (@coot) think that the intention was
-- to use strict versions.

{-------------------------------------------------------------------------------
  Wrappers that check for thunks
-------------------------------------------------------------------------------}

newSVar :: (MonadSTM m, HasCallStack, NoThunks a)
        => a -> m (StrictSVar m a)
newSVar :: forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictSVar m a)
newSVar = (a -> Maybe String) -> a -> m (StrictSVar m a)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> m (StrictSVar m a)
Strict.newSVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

newEmptySVar :: (MonadSTM m, NoThunks a) => a -> m (StrictSVar m a)
newEmptySVar :: forall (m :: * -> *) a.
(MonadSTM m, NoThunks a) =>
a -> m (StrictSVar m a)
newEmptySVar = (a -> Maybe String) -> a -> m (StrictSVar m a)
forall (m :: * -> *) a.
MonadSTM m =>
(a -> Maybe String) -> a -> m (StrictSVar m a)
Strict.newEmptySVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

{-------------------------------------------------------------------------------
  Unchecked wrappers (where we don't check for thunks)

  These will eventually be removed.
-------------------------------------------------------------------------------}

uncheckedNewSVar :: MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewSVar :: forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewSVar = a -> m (StrictSVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
Strict.newSVar

uncheckedNewEmptySVar :: MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewEmptySVar :: forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewEmptySVar = a -> m (StrictSVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
Strict.newEmptySVar