{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
module Capnp.Mutability
( Mutability (..),
MaybeMutable (..),
create,
createT,
)
where
import Control.Monad.Primitive (PrimMonad (PrimState))
import Control.Monad.ST (ST, runST)
import Data.Kind (Type)
data Mutability = Const | Mut Type
class MaybeMutable (f :: Mutability -> Type) where
thaw :: (PrimMonad m, PrimState m ~ s) => f 'Const -> m (f ('Mut s))
freeze :: (PrimMonad m, PrimState m ~ s) => f ('Mut s) -> m (f 'Const)
unsafeThaw :: (PrimMonad m, PrimState m ~ s) => f 'Const -> m (f ('Mut s))
unsafeThaw = forall (f :: Mutability -> *) (m :: * -> *) s.
(MaybeMutable f, PrimMonad m, PrimState m ~ s) =>
f 'Const -> m (f ('Mut s))
thaw
unsafeFreeze :: (PrimMonad m, PrimState m ~ s) => f ('Mut s) -> m (f 'Const)
unsafeFreeze = forall (f :: Mutability -> *) (m :: * -> *) s.
(MaybeMutable f, PrimMonad m, PrimState m ~ s) =>
f ('Mut s) -> m (f 'Const)
freeze
create :: MaybeMutable f => (forall s. ST s (f ('Mut s))) -> f 'Const
create :: forall (f :: Mutability -> *).
MaybeMutable f =>
(forall s. ST s (f ('Mut s))) -> f 'Const
create forall s. ST s (f ('Mut s))
st = forall a. (forall s. ST s a) -> a
runST (forall s. ST s (f ('Mut s))
st forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (f :: Mutability -> *) (m :: * -> *) s.
(MaybeMutable f, PrimMonad m, PrimState m ~ s) =>
f ('Mut s) -> m (f 'Const)
unsafeFreeze)
createT :: (Traversable t, MaybeMutable f) => (forall s. ST s (t (f ('Mut s)))) -> t (f 'Const)
createT :: forall (t :: * -> *) (f :: Mutability -> *).
(Traversable t, MaybeMutable f) =>
(forall s. ST s (t (f ('Mut s)))) -> t (f 'Const)
createT forall s. ST s (t (f ('Mut s)))
st = forall a. (forall s. ST s a) -> a
runST (forall s. ST s (t (f ('Mut s)))
st forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall (f :: Mutability -> *) (m :: * -> *) s.
(MaybeMutable f, PrimMonad m, PrimState m ~ s) =>
f ('Mut s) -> m (f 'Const)
unsafeFreeze)