-- 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: -- -- @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