Copyright  (c) Justin Le 2020 

License  BSD3 
Maintainer  justin@jle.im 
Stability  experimental 
Portability  nonportable 
Safe Haskell  None 
Language  Haskell2010 
Main entrypoint of the package. Abstract over different types for piecewisemutable references of values.
See https://mutable.jle.im/ for a comprehensive introduction.
Synopsis
 class Monad m => Mutable m a where
 modifyRef :: Mutable m a => Ref m a > (a > a) > m ()
 modifyRef' :: Mutable m a => Ref m a > (a > a) > m ()
 updateRef :: Mutable m a => Ref m a > (a > (a, b)) > m b
 updateRef' :: Mutable m a => Ref m a > (a > (a, b)) > m b
 newtype RefFor m a = RefFor {}
 class DefaultMutable m a r  r > a
 data GRef m a
 data MutVar s a
 newtype CoerceRef m s a = CoerceRef {
 getCoerceRef :: Ref m a
 newtype TraverseRef m f a = TraverseRef {
 getTraverseRef :: f (Ref m a)
 newtype GMutableRef m f a = GMutableRef {
 getGMutableRef :: GRef_ m f a
 data HListRef :: (Type > Type) > [Type] > Type where
 newtype VarMut a = VarMut {
 getVarMut :: a
 newtype CoerceMut s a = CoerceMut {
 getCoerceMut :: s
 newtype TraverseMut f a = TraverseMut {
 getTraverseMut :: f a
 newtype Immutable a = Immutable {
 getImmutable :: a
 newtype MutPart m s a = MutPart {
 getMutPart :: Ref m s > Ref m a
 withPart :: MutPart m s a > Ref m s > (Ref m a > m r) > m r
 freezePart :: Mutable m a => MutPart m s a > Ref m s > m a
 copyPart :: Mutable m a => MutPart m s a > Ref m s > a > m ()
 movePartInto :: Mutable m a => MutPart m s a > Ref m s > Ref m a > m ()
 movePartOver :: Mutable m a => MutPart m s a > Ref m a > Ref m s > m ()
 movePartWithin :: Mutable m a => MutPart m s a > Ref m s > Ref m s > m ()
 clonePart :: Mutable m a => MutPart m s a > Ref m s > m (Ref m a)
 unsafeFreezePart :: Mutable m a => MutPart m s a > Ref m s > m a
 modifyPart :: Mutable m a => MutPart m s a > Ref m s > (a > a) > m ()
 modifyPart' :: Mutable m a => MutPart m s a > Ref m s > (a > a) > m ()
 updatePart :: Mutable m a => MutPart m s a > Ref m s > (a > (a, b)) > m b
 updatePart' :: Mutable m a => MutPart m s a > Ref m s > (a > (a, b)) > m b
 class (Mutable m s, Mutable m a) => FieldMut (fld :: Symbol) m s a  fld s > a where
 withField :: FieldMut fld m s a => Label fld > Ref m s > (Ref m a > m b) > m b
 mutField :: forall fld m s a. FieldMut fld m s a => Label fld > Ref m s > Ref m a
 data Label (a :: Symbol) = Label
 class (Mutable m s, Mutable m a) => PosMut (i :: Nat) m s a  i s > a where
 withPos :: forall i m s a r. PosMut i m s a => Ref m s > (Ref m a > m r) > m r
 mutPos :: forall i m s a. PosMut i m s a => Ref m s > Ref m a
 class (Mutable m s, Mutable m a) => TupleMut m s a  s > a where
 withTuple :: TupleMut m s a => Ref m s > (Ref m a > m r) > m r
 hkdMutParts :: forall z m. (Generic (z (RefFor m)), Generic (z (MutPart m (z Identity))), HKDMutParts m z (Rep (z (RefFor m))) (Rep (z (MutPart m (z Identity))))) => z (MutPart m (z Identity))
 class (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z i o
 mutFst :: MutPart m (a, b) a
 mutSnd :: MutPart m (a, b) b
 mutRec :: forall a as f rec m. (Ref m (rec f as) ~ rec (RecRef m f) as, RecElem rec a a as as (RIndex a as), RecElemFCtx rec (RecRef m f)) => MutPart m (rec f as) (f a)
 coerceRef :: Ref m s ~ CoerceRef m s a => MutPart m s a
 withCoerceRef :: CoerceRef m s a > (Ref m a > m r) > m r
 data MutBranch m s a = MutBranch {
 projectBranch :: Ref m s > m (Maybe (Ref m a))
 embedBranch :: Ref m a > m (Ref m s)
 thawBranch :: Mutable m a => MutBranch m s a > a > m (Ref m s)
 freezeBranch :: Mutable m a => MutBranch m s a > Ref m s > m (Maybe a)
 moveBranch :: Mutable m s => MutBranch m s a > Ref m s > Ref m a > m ()
 copyBranch :: (Mutable m s, Mutable m a) => MutBranch m s a > Ref m s > a > m ()
 cloneBranch :: Mutable m a => MutBranch m s a > Ref m s > m (Maybe (Ref m a))
 hasBranch :: Mutable m a => MutBranch m s a > Ref m s > m Bool
 hasn'tBranch :: Mutable m a => MutBranch m s a > Ref m s > m Bool
 unsafeThawBranch :: Mutable m a => MutBranch m s a > a > m (Ref m s)
 unsafeFreezeBranch :: Mutable m a => MutBranch m s a > Ref m s > m (Maybe a)
 withBranch :: Mutable m a => MutBranch m s a > Ref m s > (Ref m a > m b) > m (Maybe b)
 withBranch_ :: Mutable m a => MutBranch m s a > Ref m s > (Ref m a > m b) > m ()
 modifyBranch :: Mutable m a => MutBranch m s a > Ref m s > (a > a) > m ()
 modifyBranch' :: Mutable m a => MutBranch m s a > Ref m s > (a > a) > m ()
 updateBranch :: Mutable m a => MutBranch m s a > Ref m s > (a > (a, b)) > m (Maybe b)
 updateBranch' :: Mutable m a => MutBranch m s a > Ref m s > (a > (a, b)) > m (Maybe b)
 constrMB :: forall ctor m s a. (Ref m s ~ GRef m s, GMutBranchConstructor ctor m (Rep s) a) => CLabel ctor > MutBranch m s a
 data CLabel (ctor :: Symbol) = CLabel
 class (GMutable m f, Mutable m a) => GMutBranchConstructor (ctor :: Symbol) m f a  ctor f > a
 type family MapRef m as where ...
 nilMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] ()
 consMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] (a, [a])
 nothingMB :: (PrimMonad m, Mutable m a) => MutBranch m (Maybe a) ()
 justMB :: (PrimMonad m, Mutable m a) => MutBranch m (Maybe a) a
 leftMB :: (PrimMonad m, Mutable m a, Mutable m b) => MutBranch m (Either a b) a
 rightMB :: (PrimMonad m, Mutable m a, Mutable m b) => MutBranch m (Either a b) b
 class Monad m => PrimMonad (m :: Type > Type)
 type family PrimState (m :: Type > Type) :: Type
Documentation
class Monad m => Mutable m a where Source #
An instance of
means that Mutable
m aa
can be stored
a mutable reference in monad m
.
The associated type
links any Ref
m aa
to the type of its
canonical mutable version.
The benefit of this typeclass, instead of just using
IORef
or MutVar
or specific mutable versions like
Vector
and MVector
, is twofold:
 Piecewisemutable values, so you can write to only one part and not
others. This also allows for cheaper "writes", even if you replace
the whole value: you don't need to ever synthesize an entire new
value, you can keep each component in a separate variable until you
freezeRef
it out. This can be especially useful for composite data types containing large structures likeVector
. Generic abstractions (similar to
Show
), so you can automatically derive instances while preserving piecewiseness. For example, the instanceinstance (Mutable m a, Mutable m b) => Mutable m (a, b)
If
a
andb
are piecwisemutable, then the instance here will appropriately utilize that fact.
To modify the specific parts of mutable values, it can be useful to use the functions in Data.Mutable.Parts.
There are facilities to automatically piecewise mutable versions for
userdefined instances of Generic
.
For example, if we have a type like:
data TwoVectors = TV { tvInt ::Vector
Int , tvDouble :: Vector Double } deriving Generic instance Mutable m TwoVectors where type Ref m TwoVectors =GRef
m TwoVectors
Then now we get:
thawRef
:: TwoVectors > m (GRef
m TwoVectors)freezeRef
::GRef
m TwoVectors > m TwoVectors
And
is now a piecewisemutable reference storing each
part in a way that can be modified separately (for example, with tools
from Data.Mutable.Parts). It does this by internally allocating two
GRef
m TwoVectorsMVector
s. If the two vectors are large, this can be much more
efficient to modify (if you are modifying several times) than by just
doing alterations on TwoVector
s. It is also much better for large
vectors if you plan on modifying only a single item in the vector.
If you are using the "higherkinded" data pattern, a la https://reasonablypolymorphic.com/blog/higherkindeddata/, then we can also do:
data TwoVectors f = TV { tvInt ::HKD
f (Vector
Int) , tvDouble :: HKD f (Vector Double) } deriving Generic instance Mutable (TwoVectorsIdentity
) where type Ref (TwoVectorsIdentity
) = TwoVectors (RefFor
m)
And now your mutable ref is literally going to be a product of the components
ghci> tvr@(TV is ds) < thawRef (TV xs ys) ghci> :t tvr TV (RefFor
IO) ghci> :t isMVector
RealWorld Int ghci> :t dsMVector
RealWorld Double
So thawRef
will actually just get you the same record type but with
the mutable versions of each field. If you modify the mutable fields,
and then later freezeRef
the whole thing, the resulting frozen value
will incorporate all of the changes to the individual fields.
In addition, there are a few more "automatically derived" instances you
can get by picking Ref
:
 Make a mutable version for any newtype wrapper, using the Mutable
 of the underlying type
newtype MyType = MT (Vector Double)
type Ref m MyType = CoerceRef m MyType (Vector Double)
 Make a mutable version of any container, where the items are all
 mutable references.
data MyContainer a = MC a a a a
deriving (Functor, Foldable, Traversable)
type Ref m (MyContainer a) = TraverseRef m MyContainer a
See https://mutable.jle.im/02mutableandref.html for more information on this typeclass and how to define instances automatically, and also
 https://mutable.jle.im/05mutableparts.html for more information on dealing with record types
 https://mutable.jle.im/06mutablebranches for more information on dealing with sum types
Nothing
type Ref m a = (v :: Type)  v > a Source #
Links the type a
to the type of its canonical "mutable version".
For example, for Vector
, the mutable version is MVector
, so
we have
type Ref m (Vector
a) =MVector
(PrimState
m) a
This means that using thawRef
on a Vector
will give you an
MVector
, using freezeRef
on a Vector
will give you
a Vector
, etc.
thawRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
a > m (Vector
s a)freezeRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
s a > m (Vector
a)copyRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
s a >Vector
a > m ()
This associated type must be unique for a
, so no two types a
can
have the same
. This makes type inference a lot more
useful: if you use Ref
m afreezeRef
on an MVector
, for instance, the
return type will be inferred to be Vector
.
The default instance is just a plain old MutVar
containing the
type. This is a valid instance, but it treats the entire type
"wholesale"  it is basically using it as a nonmutable type. You
won't get any of the performance benefits of piecewise mutation from
it, but it is useful as a base case for noncomposite types like
Int
.
There are some builtin alternative options for userdefined ADTs
with Generic
instances:
 Works for allGeneric
instances, preserves piecewise mutation  for products type Ref m a =GRef
m a
If you just set up a blank instance, the implementations of
thawRef
, freezeRef
, and copyRef
will be inferred using
DefaultMutable
.
data MyType  The default setup is OK instance Mutable m MyType  This is equivalent to the above instance Mutable m MyType type Ref m MyType =MutVar
(PrimState
m) MyType  anyGeneric
instance data MyType = MyType { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable m MyType where type Ref m MyType =GRef
m MyType
See https://mutable.jle.im/02mutableandref.html for more information on this type family and how to define instances automatically.
thawRef :: a > m (Ref m a) Source #
Thaw a pure/persistent value into its mutable version, which can
be manipulated using modifyRef
or other methods
specific for that type (like read
).
Returns the Ref
instance, so, for example, for Vector
:
thawRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
a > m (Vector
s a)
For noncomposite (like Int
), this is often called the "new var"
function, like newIORef
/ newSTRef
/ newMutVar
etc.
freezeRef :: Ref m a > m a Source #
Freeze a mutable value into its pure/persistent version.
Takes a Ref
instance, but type inference will be able to infer the
pure value's type because Ref
is injective.
For example, for Vector
:
freezeRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
s a > m (Vector
a)
For noncomposite (like Int
), this is often called the "read var"
function, like readIORef
/ readSTRef
/ readMutVar
etc.
:: Ref m a  destination to overwrite 
> a  value 
> m () 
Overwrite a mutable value by provivding a pure/persistent value.
copyRef
Returns the Ref
and the value, so, for example, for Vector
:
copyRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
s a >Vector
a > m ()
Note that if a
is a composite type (with an appropriate composite
reference), this will be done "piecewise": it'll write to each
mutable component separately.
For noncomposite (like Int
), this is often called the "write var"
function, like writeIORef
/ writeSTRef
/ writeMutVar
etc.
Deep Copymove a mutable reference on top of another, overwriting the second one.
For noncomposite types, this is the same as a thawRef
and
a copyRef
. For composite types this can be more effficient
because the copying is done piecewise, so the intermediate pure value
is never created.
cloneRef :: Ref m a > m (Ref m a) Source #
Create a deep copy of a mutable reference, allocated to a separate independent reference.
For noncomposite types, this is the same as a thawRef
and
a freezeRef
. For composite types this can be more effficient
because the cloning is done piecewise, so the intermediate pure value
is never created.
unsafeThawRef :: a > m (Ref m a) Source #
A noncopying version of thawRef
that can be more efficient for
types where the mutable representation is the same as the immutable
one (like Vector
).
This is safe as long as you never again use the original pure value, since it can potentially directly mutate it.
unsafeFreezeRef :: Ref m a > m a Source #
A noncopying version of freezeRef
that can be more efficient for
types where the mutable representation is the same as the immutable
one (like Vector
).
This is safe as long as you never again modify the mutable reference, since it can potentially directly mutate the frozen value magically.
thawRef :: DefaultMutable m a (Ref m a) => a > m (Ref m a) Source #
Thaw a pure/persistent value into its mutable version, which can
be manipulated using modifyRef
or other methods
specific for that type (like read
).
Returns the Ref
instance, so, for example, for Vector
:
thawRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
a > m (Vector
s a)
For noncomposite (like Int
), this is often called the "new var"
function, like newIORef
/ newSTRef
/ newMutVar
etc.
freezeRef :: DefaultMutable m a (Ref m a) => Ref m a > m a Source #
Freeze a mutable value into its pure/persistent version.
Takes a Ref
instance, but type inference will be able to infer the
pure value's type because Ref
is injective.
For example, for Vector
:
freezeRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
s a > m (Vector
a)
For noncomposite (like Int
), this is often called the "read var"
function, like readIORef
/ readSTRef
/ readMutVar
etc.
:: DefaultMutable m a (Ref m a)  
=> Ref m a  destination to overwrite 
> a  value 
> m () 
Overwrite a mutable value by provivding a pure/persistent value.
copyRef
Returns the Ref
and the value, so, for example, for Vector
:
copyRef
:: (PrimMonad
m, s ~PrimState
m) =>Vector
s a >Vector
a > m ()
Note that if a
is a composite type (with an appropriate composite
reference), this will be done "piecewise": it'll write to each
mutable component separately.
For noncomposite (like Int
), this is often called the "write var"
function, like writeIORef
/ writeSTRef
/ writeMutVar
etc.
:: DefaultMutable m a (Ref m a)  
=> Ref m a  destination 
> Ref m a  source 
> m () 
Deep Copymove a mutable reference on top of another, overwriting the second one.
For noncomposite types, this is the same as a thawRef
and
a copyRef
. For composite types this can be more effficient
because the copying is done piecewise, so the intermediate pure value
is never created.
cloneRef :: DefaultMutable m a (Ref m a) => Ref m a > m (Ref m a) Source #
Create a deep copy of a mutable reference, allocated to a separate independent reference.
For noncomposite types, this is the same as a thawRef
and
a freezeRef
. For composite types this can be more effficient
because the cloning is done piecewise, so the intermediate pure value
is never created.
unsafeThawRef :: DefaultMutable m a (Ref m a) => a > m (Ref m a) Source #
A noncopying version of thawRef
that can be more efficient for
types where the mutable representation is the same as the immutable
one (like Vector
).
This is safe as long as you never again use the original pure value, since it can potentially directly mutate it.
unsafeFreezeRef :: DefaultMutable m a (Ref m a) => Ref m a > m a Source #
Instances
modifyRef :: Mutable m a => Ref m a > (a > a) > m () Source #
Apply a pure function on an immutable value onto a value stored in a mutable reference.
modifyRef' :: Mutable m a => Ref m a > (a > a) > m () Source #
modifyRef
, but forces the result before storing it back in the
reference.
updateRef :: Mutable m a => Ref m a > (a > (a, b)) > m b Source #
Apply a pure function on an immutable value onto a value stored in a mutable reference, returning a result value from that function.
updateRef' :: Mutable m a => Ref m a > (a > (a, b)) > m b Source #
updateRef
, but forces the updated value before storing it back in the
reference.
A handy newtype wrapper that allows you to partially apply Ref
.
is the same as RefFor
m a
, but can be partially applied.Ref
m a
If used with HKD
, you can treat this syntactically identically as
a
.Ref
m a
Instances
Instances
class DefaultMutable m a r  r > a Source #
The default implementations of thawRef
, freezeRef
, and copyRef
dispatched for different choices of Ref
.
Basically, by specifying Ref
, you get the rest of the instance for
free.
We have the default case:
 default, if you don't specify Ref
instance Mutable m MyType
 the above is the same as:
instance Mutable m MyType
type Ref m MyType = MutVar (PrimState m) MyType
The case for any instance of Generic
:
instance Mutable m MyType type Ref m MyType = GRef m MyType
The case for the "higherkinded data" pattern a la https://reasonablypolymorphic.com/blog/higherkindeddata/:
instance Mutable m (MyTypeF Identity) type Ref m (MyTypeF Identity) = MyTypeF (RefFor m)
The case for any newtype wrapper:
newtype MyType = MT (Vector Double) instance Mutable m MyType where type Ref m MyType = CoerceRef m MyType (Vector Double)
And the case for any 'Traversable instance, where the items will all be mutable references:
data MyContainer a = MC a a a a deriving (Functor, Foldable, Traversable) instance Mutable m a => Mutable m (MyContainer a) where type Ref m (MyContainer a) = TraverseRef m MyContainer a
defaultThawRef, defaultFreezeRef, defaultCopyRef, defaultMoveRef, defaultCloneRef, defaultUnsafeThawRef, defaultUnsafeFreezeRef
Instances
Automatically generate a piecewise mutable reference for any Generic
instance.
  anyGeneric
instance data MyType = MyType { mtInt :: Int, mtDouble :: Double } deriving (Generic, Show) instance Mutable m MyType where type Ref m MyType =GRef
m MyType
ghci> r <thawRef
(MyType 3 4.5) ghci>freezeRef
r MyType 3 4.5 ghci>freezePart
(fieldMut
#mtInt) r 3 ghci>copyPart
(fieldMut #mtDouble) 1.23 ghci> freezeRef r MyType 3 1.23
Note that this is basically just a bunch of tupled refs for a product type. For a sum type (with multiple constructors), an extra layer of indirection is added to account for the dynamically changable shape.
See Data.Mutable.Parts and Data.Mutable.Branches for nice ways to inspect and mutate the internals of this type (as demonstrated above).
If the facilities in those modules are not adequate, you can also
manually crack open GRef
and work with the internals. Getting the
type of
should allow you to navigate what is going
on, if you are familiar with GHC.Generics. However, ideally, you
would never need to do this.unGRef
@MyType
Instances
(Generic a, GMutable m (Rep a)) => DefaultMutable m a (GRef m a) Source #  
Defined in Data.Mutable.Internal defaultThawRef :: a > m (GRef m a) Source # defaultFreezeRef :: GRef m a > m a Source # defaultCopyRef :: GRef m a > a > m () Source # defaultMoveRef :: GRef m a > GRef m a > m () Source # defaultCloneRef :: GRef m a > m (GRef m a) Source # defaultUnsafeThawRef :: a > m (GRef m a) Source # defaultUnsafeFreezeRef :: GRef m a > m a Source #  
Eq (GRef_ m (Rep a) ()) => Eq (GRef m a) Source #  
Ord (GRef_ m (Rep a) ()) => Ord (GRef m a) Source #  
Defined in Data.Mutable.Internal 
A MutVar
behaves like a singleelement mutable array associated
with a primitive state token.
Instances
(PrimMonad m, s ~ PrimState m) => DefaultMutable m a (MutVar s a) Source #  
Defined in Data.Mutable.Internal defaultThawRef :: a > m (MutVar s a) Source # defaultFreezeRef :: MutVar s a > m a Source # defaultCopyRef :: MutVar s a > a > m () Source # defaultMoveRef :: MutVar s a > MutVar s a > m () Source # defaultCloneRef :: MutVar s a > m (MutVar s a) Source # defaultUnsafeThawRef :: a > m (MutVar s a) Source # defaultUnsafeFreezeRef :: MutVar s a > m a Source #  
Eq (MutVar s a)  
newtype CoerceRef m s a Source #
A Ref
that works by using the Mutable
instance of an equivalent
type. This is useful for newtype wrappers, so you can use the
underlying data type's Mutable
instance.
newtype MyVec = MyVec (Vector
Double) instanceMutable
m MyVec where typeRef
m MyVec =CoerceRef
m s (Vector
Double)
The Ref m MyVec
uses the a
under the hood.MVector
Double
It's essentially a special case of GRef
for newtypes.
CoerceRef  

Instances
newtype TraverseRef m f a Source #
A Ref
that works for any instance of Traversable
, by using the
fields of the Traversable
instance to purely store mutable references.
Note that this really only makes complete sense if the Traversable
is
fixedsize, or you never modify the length of the traversable as you use
it as a reference.
If you do modify the length, copying and modifying semantics can be a bit funky:
 If copying a shorter item into a longer item ref, the "leftovers" items in the longer item are unchanged.
 If copying a longer item into a shorter item ref, the leftover items are unchanged.
ghci> r <thawTraverse
[1..10] ghci>copyTraverse
r [0,0,0,0] ghci>freezeTraverse
r [0,0,0,0,5,6,7,8,9,10] ghci>copyTraverse
r [20..50] ghci>freezeTraverse
r [20,21,22,23,24,25,26,27,28,29]
TraverseRef  

Instances
(Traversable f, Mutable m a) => DefaultMutable m (f a) (TraverseRef m f a) Source #  
Defined in Data.Mutable.Internal defaultThawRef :: f a > m (TraverseRef m f a) Source # defaultFreezeRef :: TraverseRef m f a > m (f a) Source # defaultCopyRef :: TraverseRef m f a > f a > m () Source # defaultMoveRef :: TraverseRef m f a > TraverseRef m f a > m () Source # defaultCloneRef :: TraverseRef m f a > m (TraverseRef m f a) Source # defaultUnsafeThawRef :: f a > m (TraverseRef m f a) Source # defaultUnsafeFreezeRef :: TraverseRef m f a > m (f a) Source #  
IsoHKD (TraverseRef m f :: Type > Type) (a :: Type) Source #  Use a 
Defined in Data.Mutable.Internal type HKD (TraverseRef m f) a :: Type # unHKD :: HKD (TraverseRef m f) a > TraverseRef m f a # toHKD :: TraverseRef m f a > HKD (TraverseRef m f) a #  
type HKD (TraverseRef m f :: Type > Type) (a :: Type) Source #  
Defined in Data.Mutable.Internal 
newtype GMutableRef m f a Source #
A Ref
for instances of GMutable
, which are the GHC.Generics
combinators.
GMutableRef  

Instances
Eq (GRef_ m f a) => Eq (GMutableRef m f a) Source #  
Defined in Data.Mutable.Internal (==) :: GMutableRef m f a > GMutableRef m f a > Bool # (/=) :: GMutableRef m f a > GMutableRef m f a > Bool #  
Ord (GRef_ m f a) => Ord (GMutableRef m f a) Source #  
Defined in Data.Mutable.Internal compare :: GMutableRef m f a > GMutableRef m f a > Ordering # (<) :: GMutableRef m f a > GMutableRef m f a > Bool # (<=) :: GMutableRef m f a > GMutableRef m f a > Bool # (>) :: GMutableRef m f a > GMutableRef m f a > Bool # (>=) :: GMutableRef m f a > GMutableRef m f a > Bool # max :: GMutableRef m f a > GMutableRef m f a > GMutableRef m f a # min :: GMutableRef m f a > GMutableRef m f a > GMutableRef m f a # 
data HListRef :: (Type > Type) > [Type] > Type where Source #
The mutable reference of the HList
type from genericlens.
Providing/overriding instances
Newtype wrapper that can provide any type with a Mutable
instance,
giving it a "nonpiecewise" instance. Can be useful for avoiding orphan
instances yet still utilizing autoderiving features, or for overwriting
the Mutable
instance of other instances.
For example, let's say you want to autoderive an instance for your data type:
data MyType = MT Int Double OtherType deriving Generic
This is possible if all of MyType
s fields have Mutable
instances.
However, let's say OtherType
comes from an external library that you
don't have control over, and so you cannot give it a Mutable
instance
without incurring an orphan instance.
One solution is to wrap it in VarMut
:
data MyType = MT Int Double (VarMut
OtherType)
deriving Generic
This can then be autoderived:
instance Mutable m MyType where type Ref m MyType = GRef m MyType
It can also be used to override a Mutable
instance. For example,
even if the Mutable
instance of SomeType
is piecewisemutable, the
Mutable
instance of
will be not be piecewise.VarMut
SomeType
For example, the Mutable
instance for String
is a mutable linked
list, but it might be more efficient to treat it as an atomic value to
update all at once. You can use
to get that
VarMut
String
Mutable
instance.
Instances
PrimMonad m => Mutable m (VarMut a) Source #  
Defined in Data.Mutable.Class thawRef :: VarMut a > m (Ref m (VarMut a)) Source # freezeRef :: Ref m (VarMut a) > m (VarMut a) Source # copyRef :: Ref m (VarMut a) > VarMut a > m () Source # moveRef :: Ref m (VarMut a) > Ref m (VarMut a) > m () Source # cloneRef :: Ref m (VarMut a) > m (Ref m (VarMut a)) Source # unsafeThawRef :: VarMut a > m (Ref m (VarMut a)) Source # unsafeFreezeRef :: Ref m (VarMut a) > m (VarMut a) Source #  
IsoHKD VarMut (a :: Type) Source #  Use a 
type Ref m (VarMut a) Source #  
type HKD VarMut (a :: Type) Source #  
Defined in Data.Mutable.Class 
newtype CoerceMut s a Source #
Similar to VarMut
, this allows you to overwrite the normal Mutable
instance of a type to utilize a coercible type's Mutable
instance
instead of its normal instance. It's also useful to provide an instance for
an externally defined type without incurring orphan instances.
For example, if an external library provides
newtype DoubleVec = DV (Vector Double)
and you want to use it following Vector
s Mutable
instance (via
MVector
), but you don't want to write an orphan instance like
instance Mutable m DoubleVec where typeRef
m DoubleVec =CoerceRef
m DoubleVec (Vector Double)
then you can instead use
as the
data type. This wrapped type does use the inderlying CoerceMut
DoubleVec (Vector Double)Mutable
insatnce for Vector
.
CoerceMut  

Instances
IsoHKD (CoerceMut s :: k > Type) (a :: k) Source #  Use a 
(Mutable m a, Coercible s a) => Mutable m (CoerceMut s a) Source #  
Defined in Data.Mutable.Class thawRef :: CoerceMut s a > m (Ref m (CoerceMut s a)) Source # freezeRef :: Ref m (CoerceMut s a) > m (CoerceMut s a) Source # copyRef :: Ref m (CoerceMut s a) > CoerceMut s a > m () Source # moveRef :: Ref m (CoerceMut s a) > Ref m (CoerceMut s a) > m () Source # cloneRef :: Ref m (CoerceMut s a) > m (Ref m (CoerceMut s a)) Source # unsafeThawRef :: CoerceMut s a > m (Ref m (CoerceMut s a)) Source # unsafeFreezeRef :: Ref m (CoerceMut s a) > m (CoerceMut s a) Source #  
type HKD (CoerceMut s :: k > Type) (a :: k) Source #  
Defined in Data.Mutable.Class  
type Ref m (CoerceMut s a) Source #  
Defined in Data.Mutable.Class 
newtype TraverseMut f a Source #
Similar to VarMut
, this allows you to overwrite the normal Mutable
instance for a type to utilize its Traversable
instance instead of its
normal instance. It's also useful to provide an instance for an
externally defined type without incurring orphan instances.
For example, the instance of
is
a normal list of mutable references, instead of a fullon mutable linked
list.Mutable
(TraverseMut
[] a)
TraverseMut  

Instances
Similar to VarMut
, this allows you to overwrite the normal Mutable
instance of a type to make it immutable.
For example, let's say you have a type, with the automatically derived
generic instance of Mutable
:
data MyType = MT { mtX :: Int , mtY :: Vector Double , mtZ :: String } deriving Generic instance Mutable m MyType where type Ref m MyType = GRef m MyType
This basically uses three mutable references: the Int
, the
, and the Vector
DoubleString
. However, you might want the Mutable
instance of MyType
to be immutable String
field, and so it cannot
be updated at all even when thawed. To do that, you can instead have:
data MyType = MT
{ mtX :: Int
, mtY :: Vector Double
, mtZ :: Immutable
String
}
deriving Generic
instance Mutable m MyType where
type Ref m MyType = GRef m MyType
which has that behavior. The Int
and the Vector
will be mutable
within
, but not the Ref
m MyTypeString
.
Immutable  

Instances
Monad m => Mutable m (Immutable a) Source #  
Defined in Data.Mutable.Class thawRef :: Immutable a > m (Ref m (Immutable a)) Source # freezeRef :: Ref m (Immutable a) > m (Immutable a) Source # copyRef :: Ref m (Immutable a) > Immutable a > m () Source # moveRef :: Ref m (Immutable a) > Ref m (Immutable a) > m () Source # cloneRef :: Ref m (Immutable a) > m (Ref m (Immutable a)) Source # unsafeThawRef :: Immutable a > m (Ref m (Immutable a)) Source # unsafeFreezeRef :: Ref m (Immutable a) > m (Immutable a) Source #  
IsoHKD Immutable (a :: Type) Source #  Use an 
type Ref m (Immutable a) Source #  
Defined in Data.Mutable.Class  
type HKD Immutable (a :: Type) Source #  
Defined in Data.Mutable.Class 
Parts
newtype MutPart m s a Source #
A
is a way to "zoom into" an MutPart
m s aa
, as a part of
a mutable reference on s
. This allows you to only modify a single
a
part of the s
, without touching the rest. It's spiritually
similar to a Lens' s a
.
If MutBranch
is for sum types, then MutPart
is
for product types.
See https://mutable.jle.im/05mutableparts.html for an introduction to this type.
An example that is commonly found in the ecosystem is something like
(flipped) write :: Int >
from
Data.Vector.Mutable  MVector
s a > a > m ()write 3 ::
, for instance, lets you modify a specific part of the vector
without touching the rest.MVector
s a > a >
m ()
You would use a MutPart
using freezePart
, copyPart
,
modifyPart
, etc.
For noncomposite types, there won't really be any meaningful values. However, we have them for many composite types. For example, for tuples:
mutFst
::MutPart
m (a, b) amutSnd
:: MutPart m (a, b) b
ghci> r <thawRef
(2, 4) ghci>copyPart
mutFst r 100 ghci>freezeRef
r (100, 4)
If you are using GRef
as an automaticallydefined mutable reference,
then the easiest way to create these for your mutable types are with
fieldMut
and posMut
.
If you are using the "Higherkinded data" pattern, then there's an easy
way to generate a MutPart
for every single field, if you have
a product type  see hkdMutParts
for more information.
MutPart  

Instances
(Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z (K1 i (RefFor m c) :: k > Type) (K1 i (MutPart m (z Identity) c) :: k > Type) Source #  
Defined in Data.Mutable.Parts  
Category (MutPart m :: Type > Type > Type) Source #  
IsoHKD (MutPart m s :: Type > Type) (a :: Type) Source #  
type HKD (MutPart m s :: Type > Type) (a :: Type) Source #  
:: Mutable m a  
=> MutPart m s a  
> Ref m s  bigger type (destination) 
> Ref m a  smaller type (source) 
> m () 
With a MutPart
, copy a Ref
containing a subvalue into a specific
part of a larger Ref
.
data MyType = MT { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable m MyType where type Ref m MyType = GRef m MyType
ghci> x < thawRef $ MyType 3 4.5 ghci> y < thawRef $ 100 ghci> movePartInto (fieldMut #mtInt) x y ghci> freezeRef x MyType 100 4.5
:: Mutable m a  
=> MutPart m s a  
> Ref m a  smaller type (destination) 
> Ref m s  bigger type (source) 
> m () 
With a MutPart
, copy a specific part of a larger Ref
into a Ref
of the smaller subvalue value.
data MyType = MT { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable m MyType where type Ref m MyType = GRef m MyType
ghci> x < thawRef $ MyType 3 4.5 ghci> y < thawRef $ 100 ghci> movePartOver (fieldMut #mtInt) y x ghci> freezeRef y 3
With a MutPart
, copy a specific part of a large Ref
into that
same part in another large Ref
.
data MyType = MT { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable m MyType where type Ref m MyType = GRef m MyType
ghci> x < thawRef $ MyType 3 4.5 ghci> y < thawRef $ MyType 100 12.34 ghci> movePartWithin (fieldMut #mtInt) x y ghci> freezeRef x MyType 100 4.5
clonePart :: Mutable m a => MutPart m s a > Ref m s > m (Ref m a) Source #
Clone out a subvalue of a larger Ref
.
unsafeFreezePart :: Mutable m a => MutPart m s a > Ref m s > m a Source #
A noncopying version of unsafeFreezeRef
that can be more efficient for
types where the mutable representation is the same as the immutable
one (like Vector
).
This is safe as long as you never again modify the mutable reference, since it can potentially directly mutate the frozen value magically.
modifyPart' :: Mutable m a => MutPart m s a > Ref m s > (a > a) > m () Source #
modifyPart
, but forces the result before storing it back in the
reference.
updatePart' :: Mutable m a => MutPart m s a > Ref m s > (a > (a, b)) > m b Source #
updatePart
, but forces the result before storing it back in the
reference.
Builtin
MutPart
Field
class (Mutable m s, Mutable m a) => FieldMut (fld :: Symbol) m s a  fld s > a where Source #
Create a MutPart
for a field name. Should work for any type with
one constructor whose mutable reference is GRef
. See fieldMut
for
usage directions.
Mostly leverages the power of Data.Generics.Product.Fields.
Create a MutPart
for a field name. Should work for any type with
one constructor whose mutable reference is GRef
.
Is meant to be used with OverloadedLabels:
data MyType = MyType { mtInt :: Int, mtDouble :: Double }
deriving (Generic, Show)
instance Mutable m MyType where
type Ref m MyType = GRef
m MyType
ghci> r <thawRef
(MyType 3 4.5) ghci>freezePart
(fieldMut
#mtInt) r 3 ghci>copyPart
(fieldMut #mtDouble) 1.23 ghci>freezeRef
r MyType 3 1.23
However, you can use it without OverloadedLabels by using Label
with
TypeApplications:
ghci>freezePart
(fieldMut
(Label
@"mtInt")) r 3
This and posMut
are the main ways to generate a MutPart
for
a type whose mutable reference is GRef
. Note that because all of
the lookups are done at compiletime, fieldMut
and posMut
have
more or less identical performance characteristics.
:: FieldMut fld m s a  
=> Label fld  field label (usually given using OverloadedLabels, @#blah) 
> Ref m s  Larger record reference 
> Ref m a  Internal mutable field 
A helpful wrapper around
. Directly
use a getMutPart
(fieldMut
#blah)fieldMut
to access a mutable field.
Proxy for label type
Position
class (Mutable m s, Mutable m a) => PosMut (i :: Nat) m s a  i s > a where Source #
Create a MutPart
for a position in a product type. Should work for any
type with one constructor whose mutable reference is GRef
. See
posMut
for usage directions.
Mostly leverages the power of Data.Generics.Product.Positions.
posMut :: MutPart m s a Source #
Create a MutPart
for a position in a product type. Should work for any
type with one constructor whose mutable reference is GRef
.
Meant to be used with TypeApplications:
data MyType = MyType Int Double
deriving (Generic, Show)
instance Mutable m MyType where
type Ref m MyType = GRef
m MyType
ghci> r <thawRef
(MyType 3 4.5) ghci>freezePart
(posMut
@1) r 3 ghci>copyPart
(posMut @2) 1.23 ghci>freezeRef
r MyType 3 1.23
This and fieldMut
are the main ways to generate a MutPart
for
a type whose mutable reference is GRef
. Note that because all of
the lookups are done at compiletime, posMut
and fieldMut
have
more or less identical performance characteristics.
A helpful wrapper around
. Directly
use a getMutPart
(posMut
@n)posMut
to access a mutable field.
Tuple
class (Mutable m s, Mutable m a) => TupleMut m s a  s > a where Source #
Create a MutPart
splitting out a product type into a tuple of refs
for every field in that product type. Should work for any type with one
constructor whose mutable reference is GRef
. See tupleMut
for usage
directions.
Mostly leverages the power of Data.Generics.Product.HList.
tupleMut :: MutPart m s a Source #
Create a MutPart
splitting out a product type into a tuple of refs
for every field in that product type. Should work for any type with one
constructor whose mutable reference is GRef
.
Probably most easily used using withTuple
:
data MyType = MyType Int Double
deriving (Generic, Show)
instance Mutable m MyType where
type Ref m MyType = GRef
m MyType
Now there is an instance of
.TupleMut
m MyType (Int, Double)
ghci> r <thawRef
(MyType 3 4.5) ghci>withTuple
r $ (rI, rD) > do ..modifyRef
rI negate .. modifyRef rD (* 2) ghci>freezeRef
r MyType (3) 9
As can be seen, within the lambda, we can get access to every
mutable reference inside a MyType
reference.
Performancewise, this appears to be faster than fieldMut
and
posMut
when using a single reference, but slower if using all
references.
:: TupleMut m s a  
=> Ref m s  Larger record reference 
> (Ref m a > m r)  What to do with each mutable field. The

> m r 
A helpful wrapper over
. Directly operate on
the items in the data type, getting the references as a tuple. See
withPart
tupleMut
tupleMut
for more details on when this should work.
data MyType = MyType Int Double
deriving (Generic, Show)
instance Mutable m MyType where
type Ref m MyType = GRef
m MyType
ghci> r <thawRef
(MyType 3 4.5) ghci>withTuple
r $ (rI, rD) > do ..modifyRef
rI negate .. modifyRef rD (* 2) ghci>freezeRef
r MyType (3) 9
HigherKinded Data
hkdMutParts :: forall z m. (Generic (z (RefFor m)), Generic (z (MutPart m (z Identity))), HKDMutParts m z (Rep (z (RefFor m))) (Rep (z (MutPart m (z Identity))))) => z (MutPart m (z Identity)) Source #
If you are using the "higherkinded data" pattern, a la
https://reasonablypolymorphic.com/blog/higherkindeddata/, and you
have the appropriate instance for Ref
, then you can use this to
generate a MutPart
for every field, if you have a type with only one
constructor.
data MyTypeF f = MT { mtInt :: f Int , mtDouble :: f Double } deriving Generic instance Mutable (MyTypeFIdentity
) where type Ref (MyTypeFIdentity
) = MyTypeF (RefFor
m) mx :: MutPart m (MyTypeF Identity) (Vector
Int) my :: MutPart m (MyTypeF Identity) (Vector Double) MT mx my = hkdMutParts @MyTypeF
ghci> r < thawRef (MT 3 4.5) ghci>freezePart
mx r 3 ghci>copyPart
(mtDouble (hkdMutParts @MyTypeF)) r 12.3 ghci>freezeRef
r MT 3 12.3
Performancewise, this is about equivalent to fieldMut
and posMut
for the most part, so the main advantage would be purely syntactical. If
performance is an issue, you should benchmark all the different ways
just to be sure. As a general rule, it seems like deep nested accesses
are faster with composition of fieldMut
and posMut
, but immediate
shallow access is often faster with hkdMutParts
...but this probably
does vary on a casebycase basis.
class (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z i o Source #
Typeclass used to implement hkdMutParts
. See documentation of
hkdMutParts
for more information.
hkdMutParts_
Instances
(Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m), (TypeError (Text "Cannot use hkdMutParts for uninhabited types: " :<>: ShowType z) :: Constraint)) => HKDMutParts m z (V1 :: k > Type) (V1 :: k > Type) Source #  
Defined in Data.Mutable.Parts hkdMutParts_ :: (z (RefFor m) > V1 a) > V1 a  
(Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z (U1 :: k > Type) (U1 :: k > Type) Source #  
Defined in Data.Mutable.Parts hkdMutParts_ :: (z (RefFor m) > U1 a) > U1 a  
(Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m), (TypeError (Text "Cannot use hkdMutParts for sum types: " :<>: ShowType z) :: Constraint)) => HKDMutParts m z (i :+: i' :: k > Type) (o :: k > Type) Source #  
Defined in Data.Mutable.Parts hkdMutParts_ :: (z (RefFor m) > (i :+: i') a) > o a  
(HKDMutParts m z i o, HKDMutParts m z i' o') => HKDMutParts m z (i :*: i' :: k > Type) (o :*: o' :: k > Type) Source #  
Defined in Data.Mutable.Parts hkdMutParts_ :: (z (RefFor m) > (i :*: i') a) > (o :*: o') a  
(Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z (K1 i (RefFor m c) :: k > Type) (K1 i (MutPart m (z Identity) c) :: k > Type) Source #  
Defined in Data.Mutable.Parts  
HKDMutParts m z i o => HKDMutParts m z (M1 a b i :: k > Type) (M1 a b o :: k > Type) Source #  
Defined in Data.Mutable.Parts hkdMutParts_ :: (z (RefFor m) > M1 a b i a0) > M1 a b o a0 
Other
mutRec :: forall a as f rec m. (Ref m (rec f as) ~ rec (RecRef m f) as, RecElem rec a a as as (RIndex a as), RecElemFCtx rec (RecRef m f)) => MutPart m (rec f as) (f a) Source #
A MutPart
for a field in a vinyl Rec
, automatically
generated as the first field with a matching type. This is polymorphic
to work over both Rec
and ARec
.
ghci> r <thawRef
$ [1,2,3]:&
[True, False] :&RNil
ghci> modifyPart (mutRec @Bool) r reverse ghci> freezeRef r [1,2,3] :& [False, True] :& RNil
withCoerceRef :: CoerceRef m s a > (Ref m a > m r) > m r Source #
Handy wrapper over
.getMutPart
coerceRef
Branches
A
represents the information that MutBranch
m s as
could
potentially be an a
. Similar in spirit to a Prism' s a
.
means that MutBranch
m s aa
is one potential option that s
could be in, or that s
is a sum type and a
is one of the
branches/constructors.
See https://mutable.jle.im/06mutablebranches.html for an introduction to this module.
If MutPart
is for product types, then MutBranch
is for sum types.
In this case, "branch" means "potential option". For example, the
branches of Either
are Left
and Right
.
The simplest way to make these is by using constrMB
. For instance, to
get the two branches of an Either
:
constrMB #_Left :: MutBranch m (Either a b) a constrMB #_Right :: MutBranch m (Either a b) b
ghci> r <thawRef
(Left 10) ghci>freezeBranch
(constrMB
#_Left) r Just 10 ghci> freezeBranch (constrMB #_Right) r Nothing
It uses OverloadedLabels, but requires an underscore before the constructor name due to limitations in the extension.
One nice way to use these is with withBranch_
:
ghci> r <thawRef
(Just 10) ghci>withBranch_
(constrMB #_Just) $ i > i
is an Int ref .. modifyRef i (+ 1) ghci>freezeRef
r Just 11
ghci> r < thawRef Nothing
ghci> withBranch_ (constrMB #_Just) $ i >  i
is an Int ref
.. modifyRef i (+ 1)
ghci> freezeRef r
Nothing
Perhaps the most useful usage of this abstraction is for recursive data types.
data List a = Nil  Cons a (List a) deriving Generic instance Mutable m a =>Mutable
m (List a) where type Ref m (List a) =GRef
m (List a)
is now a mutable linked list! Once we make the
GRef
m (List a)MutBranch
for the nil and cons cases:
nilBranch :: MutBranch m (List a) () nilBranch = constrMB #_Nil consBranch :: MutBranch m (List a) (a, List a) consBranch = constrMB #_Cons
Here is a function to check if a linked list is currently empty:
isEmpty :: (PrimMonad m, Mutable m a) => Ref m (List a) > m Bool isEmpty = hasBranch nilBranch
Here is one to "pop" a mutable linked list, giving us the first value and shifting the rest of the list up.
popStack :: (PrimMonad m, Mutable m a) => Ref m (List a) > m (Maybe a) popStack r = do c < projectBranch consBranch r case c of Nothing > pure Nothing Just (x, xs) > do moveRef r xs Just $ freezeRef x
And here is a function to concatenate a second linked list to the end of a first one.
concatLists :: (PrimMonad m, Mutable m a) => Ref m (List a) > Ref m (List a) > m () concatLists l1 l2 = do c < projectBranch consBranch l1 case c of Nothing > moveRef l1 l2 Just (_, xs) > concatLists xs l2
MutBranch  

thawBranch :: Mutable m a => MutBranch m s a > a > m (Ref m s) Source #
With a MutBranch
, thaw an a
into a mutable s
on that branch.
ghci> r <thawBranch
(constrMB
#_Left) 10 ghci>freezeRef
r Left 10
:: Mutable m a  
=> MutBranch m s a  How to check if is 
> Ref m s  Structure to read out of 
> m (Maybe a) 
With a MutBranch
, read out a specific a
branch of an s
, if it exists.
ghci> r <thawRef
(Left 10) ghci>freezeBranch
(constrMB
#_Left) r Just 10 ghci> freezeBranch (constrMB #_Right) r Nothing
moveBranch :: Mutable m s => MutBranch m s a > Ref m s > Ref m a > m () Source #
With a MutBranch
, overwrite an s
as an a
, on that branch.
ghci> r < thawRef (Left 10) ghci> s < thawRef 100 ghci> moveBranch (constrMB #_Left) r s ghci> freezeRef r Left 100 ghci> t < thawRef True ghci> moveBranch (constrMB #_Right) r t ghci> freezeRef r Right True
:: (Mutable m s, Mutable m a)  
=> MutBranch m s a  How to check if 
> Ref m s  Structure to write into 
> a  Value to set 
> m () 
With a MutBranch
, set s
to have the branch a
.
ghci> r <thawRef
(Left 10) ghci>copyBranch
(constrMB
#_Left) r 5678 ghci>freezeRef
r Left 5678 ghci> copyBranch (constrMB #_Right) r True ghci> freezeRef r Right True
:: Mutable m a  
=> MutBranch m s a  How to check if 
> Ref m s  Structure to read out of 
> m (Maybe (Ref m a)) 
With a MutBranch
, attempt to clone out a branch of a mutable
s
, if possible.
ghci> r < thawRef (Left 10) ghci> s < cloneBranch (constrMB #_Left) ghci> case s of Just s' > freezeRef s' 10
ghci> r < thawRef (Right True) ghci> s < cloneBranch (constrMB #_Left) ghci> case s of Nothing > "it was Right" "it was Right"
hasBranch :: Mutable m a => MutBranch m s a > Ref m s > m Bool Source #
Check if an s
is currently a certain branch a
.
hasn'tBranch :: Mutable m a => MutBranch m s a > Ref m s > m Bool Source #
Check if an s
is not currently a certain branch a
.
unsafeThawBranch :: Mutable m a => MutBranch m s a > a > m (Ref m s) Source #
A noncopying version of thawBranch
that can be more efficient for
types where the mutable representation is the same as the immutable one
(like Vector
).
This is safe as long as you never again use the original pure value, since it can potentially directly mutate it.
:: Mutable m a  
=> MutBranch m s a  How to check if is 
> Ref m s  Structure to read out of 
> m (Maybe a) 
A noncopying version of freezeBranch
that can be more efficient
for types where the mutable representation is the same as the immutable
one (like Vector
).
This is safe as long as you never again modify the mutable reference, since it can potentially directly mutate the frozen value magically.
:: Mutable m a  
=> MutBranch m s a  How to check if is 
> Ref m s  Structure to read out of and write into 
> (Ref m a > m b)  Action to perform on the 
> m (Maybe b) 
With a MutBranch
, if an s
is on the a
branch, perform an action
on the a
reference and overwrite the s
with the modified a
.
Returns the result of the action, if a
was found.
ghci> r <thawRef
(Just 10) ghci>withBranch_
(constrMB
#_Just) $ i > i
is an Int ref ..modifyRef
i (+ 1) ghci>freezeRef
r Just 11
ghci> r < thawRef Nothing
ghci> withBranch_ (constrMB #_Just) $ i >  i
is an Int ref
.. modifyRef i (+ 1)
ghci> freezeRef r
Nothing
:: Mutable m a  
=> MutBranch m s a  How to check if is 
> Ref m s  Structure to read out of and write into 
> (Ref m a > m b)  Action to perform on the 
> m () 
withBranch
, but discarding the returned value.
:: Mutable m a  
=> MutBranch m s a  How to check if 
> Ref m s  Structure to read out of and write into 
> (a > a)  Pure function modifying 
> m () 
With a MutBranch
, run a pure function over a potential branch a
of
s
. If s
is not on that branch, leaves s
unchanged.
ghci> r <thawRef
(Just 10) ghci>modifyBranch
(constrMB
#_Just) r (+ 1) ghci> freezeRef r Just 11
ghci> r < thawRef Nothing ghci> modifyBranch (constrMB #_Just) r (+ 1) ghci> freezeRef r Nothing
:: Mutable m a  
=> MutBranch m s a  How to check if 
> Ref m s  Structure to read out of and write into 
> (a > a)  Pure function modifying 
> m () 
modifyBranch
, but forces the result before storing it back in the
reference.
:: Mutable m a  
=> MutBranch m s a  How to check if 
> Ref m s  Structure to read out of and write into 
> (a > (a, b))  
> m (Maybe b) 
With a MutBranch
, run a pure function over a potential branch a
of
s
. The function returns the updated a
and also an output value to
observe. If s
is not on that branch, leaves s
unchanged.
ghci> r <thawRef
(Just 10) ghci>updateBranch
(constrMB
#_Just) r $ i > (i + 1, show i) Just "10" ghci>freezeRef
r Just 11
ghci> r < thawRef Nothing ghci> updateBranch (constrMB #_Just) r $ i > (i + 1, show i) Nothing ghci> freezeRef r Nothing
:: Mutable m a  
=> MutBranch m s a  How to check if 
> Ref m s  Structure to read out of and write into 
> (a > (a, b))  
> m (Maybe b) 
updateBranch
, but forces the result before storing it back in the
reference.
Builtin
MutBranch
Using GHC Generics
constrMB :: forall ctor m s a. (Ref m s ~ GRef m s, GMutBranchConstructor ctor m (Rep s) a) => CLabel ctor > MutBranch m s a Source #
Create a MutBranch
for any data type with a Generic
instance by
specifying the constructor name using OverloadedLabels
ghci> r <thawRef
(Left 10) ghci>freezeBranch
(constrMB
#_Left) r Just 10 ghci> freezeBranch (constrMB #_Right) r Nothing
Note that due to limitations in OverloadedLabels, you must prefix the constructor name with an undescore.
There also isn't currently any way to utilize OverloadedLabels with
operator identifiers, so using it with operator constructors (like :
and []
) requires explicit TypeApplications:
 MutBranch
focusing on the cons case of a list consMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] (a, [a]) consMB =constrMB
(CLabel
@":")
data CLabel (ctor :: Symbol) Source #
A version of Label
that removes an underscore at
the beginning when used with XOverloadedLabels. Used to specify
constructors, since labels are currently not able to start with capital
letters.
Instances
ctor_ ~ AppendSymbol "_" ctor => IsLabel ctor_ (CLabel ctor) Source #  
Defined in Data.Mutable.Branches 
class (GMutable m f, Mutable m a) => GMutBranchConstructor (ctor :: Symbol) m f a  ctor f > a Source #
Typeclass powering constrMB
using GHC Generics.
Heavily inspired by Data.Generics.Sum.Constructors.
gmbcProj, gmbcEmbed
Instances
(PrimMonad m, Mutable m a, GMutBranchSum ctor (HasCtorP ctor l) m l r a) => GMutBranchConstructor ctor m (l :+: r :: k > Type) a Source #  
(GMutable m f, Mutable m a, GIsList (GRef_ m f) (GRef_ m f) (MapRef m as) (MapRef m as), GIsList f f as as, ListTuple a as, ListTuple b (MapRef m as), Ref m a ~ b) => GMutBranchConstructor ctor m (M1 C (MetaCons ctor fixity fields) f :: Type > Type) a Source #  
GMutBranchConstructor ctor m f a => GMutBranchConstructor ctor m (M1 D meta f :: k > Type) a Source #  
type family MapRef m as where ... Source #
Useful type family to
over every item in a typelevel listRef
m
ghci> :kind! MapRef IO '[Int, V.Vector Double] '[ MutVar RealWorld Int, MVector RealWorld Double ]
For common types
nilMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] () Source #
MutBranch
focusing on the nil case of a list
consMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] (a, [a]) Source #
MutBranch
focusing on the cons case of a list
Reexports
class Monad m => PrimMonad (m :: Type > Type) #
Class of monads which can perform primitive statetransformer actions
Instances
PrimMonad IO  
PrimMonad (ST s)  
PrimMonad m => PrimMonad (ListT m)  
PrimMonad m => PrimMonad (MaybeT m)  
PrimMonad m => PrimMonad (IdentityT m)  
(Error e, PrimMonad m) => PrimMonad (ErrorT e m)  
PrimMonad m => PrimMonad (ExceptT e m)  
PrimMonad m => PrimMonad (StateT s m)  
PrimMonad m => PrimMonad (StateT s m)  
(Monoid w, PrimMonad m) => PrimMonad (WriterT w m)  
(Monoid w, PrimMonad m) => PrimMonad (WriterT w m)  
(Monoid w, PrimMonad m) => PrimMonad (AccumT w m)  Since: primitive0.6.3.0 
PrimMonad m => PrimMonad (SelectT r m)  
PrimMonad m => PrimMonad (ContT r m)  Since: primitive0.6.3.0 
PrimMonad m => PrimMonad (ReaderT r m)  
(Monoid w, PrimMonad m) => PrimMonad (RWST r w s m)  
(Monoid w, PrimMonad m) => PrimMonad (RWST r w s m)  
type family PrimState (m :: Type > Type) :: Type #
State token type