-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Freezing, thawing, and copy elision
--
-- This library provides a class for types which present the same
-- underlying data in both an immutable (frozen) as well as a mutable
-- (thawed) form, and various functions to manipulate them. Some of the
-- functions allow for copy elision.
--
-- Instances are provided for the array types from the
-- primitive, array, and vector packages, but
-- this is mainly for completeness: there is nothing these instances do
-- which vector doesn't already do better. The main purpose,
-- rather, is to assist new types, for instance types whose
-- implementation relies on destructive-update foreign imports, and cases
-- when writing a full stream fusion framework isn't practical.
--
-- There are three modules:
--
--
-- - Data.PhaseChange This module exports the class without its
-- methods, together with functions which guarantee referential
-- transparency (provided that instances are well-behaved). This is the
-- module you should normally import to work with PhaseChangeable
-- data.
-- - Data.PhaseChange.Unsafe This module exports functions which
-- can break referential transparency if they are used improperly. Be
-- careful.
-- - Data.PhaseChange.Impl This module exports the class along
-- with its methods. Import it if you want to define a new instance.
--
@package phasechange
@version 0.1
-- | This module provides functions on PhaseChangeable data which can break
-- referential transparency if used incorrectly. For safe functions, see
-- Data.PhaseChange. To write an instance, see
-- Data.PhaseChange.Impl.
module Data.PhaseChange.Unsafe
-- | Returns the input argument viewed as a mutable type. The input
-- argument must not be used afterwards.
unsafeThaw :: (Immutable imm, MonadST mST, s ~ World mST) => imm -> mST (Thawed imm s)
-- | Returns the input argument viewed as an immutable type. The input
-- argument must not be used afterwards.
unsafeFreeze :: (Mutable mut, MonadST mST, s ~ World mST) => mut s -> mST (Frozen mut)
-- | Read a value from immutable data with a reading-computation on mutable
-- data. This function is referentially transparent as long as the
-- computation does not mutate its input argument, but there is no way to
-- enforce this.
readWith :: Immutable imm => (forall s. Thawed imm s -> ST s a) -> imm -> a
unsafeThaw1 :: (PhaseChange (imm a) (M1 mut a), MonadST mST, s ~ World mST) => imm a -> mST (mut s a)
unsafeFreeze1 :: (PhaseChange (imm a) (M1 mut a), MonadST mST, s ~ World mST) => mut s a -> mST (imm a)
readWith1 :: PhaseChange (imm a) (M1 mut a) => (forall s. mut s a -> ST s b) -> imm a -> b
unsafeThaw2 :: (PhaseChange (imm a b) (M2 mut a b), MonadST mST, s ~ World mST) => imm a b -> mST (mut s a b)
unsafeFreeze2 :: (PhaseChange (imm a b) (M2 mut a b), MonadST mST, s ~ World mST) => mut s a b -> mST (imm a b)
readWith2 :: PhaseChange (imm a b) (M2 mut a b) => (forall s. mut s a b -> ST s c) -> imm a b -> c
-- | This module allows you to write instances for PhaseChangeable types.
-- To work with PhaseChangeable data, see Data.PhaseChange. For
-- unsafe functions, see Data.PhaseChange.Unsafe.
module Data.PhaseChange.Impl
-- | The PhaseChange class ties together types which provide a
-- mutable and an immutable view on the same data. The mutable type must
-- have a phantom type parameter representing the state thread it is
-- being used in. Many types have this type parameter in the wrong place
-- (not at the end): instances for them can be provided using the
-- M1 and M2 newtypes.
class (Thawed imm ~ mut, Frozen mut ~ imm) => PhaseChange (imm :: *) (mut :: * -> *) where type family Thawed imm :: * -> * type family Frozen mut :: *
unsafeThawImpl :: PhaseChange imm mut => imm -> ST s (Thawed imm s)
unsafeFreezeImpl :: PhaseChange imm mut => mut s -> ST s (Frozen mut)
copyImpl :: PhaseChange imm mut => mut s -> ST s (mut s)
-- | Newtype for mutable types whose state thread parameter is in the
-- second-to-last position
newtype M1 mut a s
M1 :: mut s a -> M1 mut a s
unM1 :: M1 mut a s -> mut s a
-- | Newtype for mutable types whose state thread parameter is in the
-- third-to-last position
newtype M2 mut a b s
M2 :: mut s a b -> M2 mut a b s
unM2 :: M2 mut a b s -> mut s a b
-- | This module provides referentially transparent functions for working
-- with PhaseChangeable data. For functions that can break referential
-- transparency, see Data.PhaseChange.Unsafe. If you want to write
-- instances, see Data.PhaseChange.Impl.
module Data.PhaseChange
-- | The PhaseChange class ties together types which provide a
-- mutable and an immutable view on the same data. The mutable type must
-- have a phantom type parameter representing the state thread it is
-- being used in. Many types have this type parameter in the wrong place
-- (not at the end): instances for them can be provided using the
-- M1 and M2 newtypes.
class (Thawed imm ~ mut, Frozen mut ~ imm) => PhaseChange (imm :: *) (mut :: * -> *) where type family Thawed imm :: * -> * type family Frozen mut :: *
type Mutable mut = PhaseChange (Frozen mut) mut
type Immutable imm = PhaseChange imm (Thawed imm)
-- | Get a copy of immutable data in mutable form.
thaw :: (Immutable imm, MonadST mST, s ~ World mST) => imm -> mST (Thawed imm s)
-- | Get a copy of mutable data in immutable form.
freeze :: (Mutable mut, MonadST mST, s ~ World mST) => mut s -> mST (Frozen mut)
-- | Make a copy of mutable data.
copy :: (Mutable mut, MonadST mST, s ~ World mST) => mut s -> mST (mut s)
-- | Produce immutable data from a mutating computation. No copies are
-- made.
frozen :: Mutable mut => (forall s. ST s (mut s)) -> Frozen mut
-- | Make an update of immutable data by applying a mutating action. This
-- function allows for copy elision.
--
-- Each chain of updateWiths makes only one copy. A chain of
-- updateWiths on top of a frozen makes no copies.
updateWith :: Mutable mut => (forall s. mut s -> ST s ()) -> Frozen mut -> Frozen mut
-- | Newtype for mutable types whose state thread parameter is in the
-- second-to-last position
newtype M1 mut a s
M1 :: mut s a -> M1 mut a s
unM1 :: M1 mut a s -> mut s a
-- | Newtype for mutable types whose state thread parameter is in the
-- third-to-last position
newtype M2 mut a b s
M2 :: mut s a b -> M2 mut a b s
unM2 :: M2 mut a b s -> mut s a b
thaw1 :: (PhaseChange (imm a) (M1 mut a), MonadST mST, s ~ World mST) => imm a -> mST (mut s a)
freeze1 :: (PhaseChange (imm a) (M1 mut a), MonadST mST, s ~ World mST) => mut s a -> mST (imm a)
copy1 :: (PhaseChange (imm a) (M1 mut a), MonadST mST, s ~ World mST) => mut s a -> mST (mut s a)
frozen1 :: PhaseChange (imm a) (M1 mut a) => (forall s. ST s (mut s a)) -> imm a
updateWith1 :: PhaseChange (imm a) (M1 mut a) => (forall s. mut s a -> ST s ()) -> imm a -> imm a
thaw2 :: (PhaseChange (imm a b) (M2 mut a b), MonadST mST, s ~ World mST) => imm a b -> mST (mut s a b)
freeze2 :: (PhaseChange (imm a b) (M2 mut a b), MonadST mST, s ~ World mST) => mut s a b -> mST (imm a b)
copy2 :: (PhaseChange (imm a b) (M2 mut a b), MonadST mST, s ~ World mST) => mut s a b -> mST (mut s a b)
frozen2 :: PhaseChange (imm a b) (M2 mut a b) => (forall s. ST s (mut s a b)) -> imm a b
updateWith2 :: PhaseChange (imm a b) (M2 mut a b) => (forall s. mut s a b -> ST s ()) -> imm a b -> imm a b