h$D釴      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~None'(./29>?n7mutable=Automatically generate a piecewise mutable reference for any  instance.  -- | any  instance data MyType = MyType { mtInt :: Int, mtDouble :: Double } deriving (Generic, Show) instance Mutable s MyType where type Ref s MyType =  s MyType   ghci> r <- & (MyType 3 4.5) ghci> ' r MyType 3 4.5 ghci>  ( #mtInt) r 3 ghci>  ; (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 , and work with the internals. Getting the type of  @MyType should allow you to navigate what is going on, if you are familiar with  GHC.Generics6. However, ideally, you would never need to do this.mutableA % for instances of , which are the  GHC.Generics combinators. mutableWraps  in a mutable reference. Used internally to represent generic sum references.mutable"Class for automatic generation of % for  instances. See  for more information.mutableA "%%" that can be used to give a default $ instance that is immutable. Nothing is allocated ever, all attempts to modify it will be ignored, and ') will just get the original thawed value.#Really only exists to be used with  .mutableA % that works by using the $ instance of an equivalent type. This is useful for newtype wrappers, so you can use the underlying data type's $ instance. newtype MyVec = MyVec (   Double) instance $ s MyVec where type % s MyVec =  s s (   Double) The  Ref s MyVec uses the a   Double under the hood.#It's essentially a special case of  for newtypes.mutableA % that works for any instance of , by using the fields of the  instance to purely store mutable references.7Note that this really only makes complete sense if the  is fixed-size, 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 <- - [1..10] ghci> / r [0,0,0,0] ghci> . r [0,0,0,0,5,6,7,8,9,10] ghci> / r [20..50] ghci> .# r [20,21,22,23,24,25,26,27,28,29] mutable;A handy newtype wrapper that allows you to partially apply %.  m a is the same as % s a, but can be partially applied. If used with 5, you can treat this syntactically identically as a % s a.mutableThe default implementations of &, ', and (& dispatched for different choices of %.Basically, by specifying %-, you get the rest of the instance for free.We have the default case: !-- default, if you don't specify % instance Mutable s MyType -- the above is the same as: instance Mutable s MyType type Ref s MyType = MutVar s) MyType The case for any instance of : instance Mutable s MyType type Ref s MyType = GRef s MyType 4The case for the "higher-kinded data" pattern a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/: instance Mutable s (MyTypeF Identity) type Ref s (MyTypeF Identity) = MyTypeF (RefFor s) !The case for any newtype wrapper: newtype MyType = MT (Vector Double) instance Mutable s MyType where type Ref s MyType = CoerceRef s 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 s a => Mutable s (MyContainer a) where type Ref s (MyContainer a) = TraverseRef s MyContainer a $mutableAn instance of $ s a means that a) can be stored a mutable reference in a  m (where s is the mutable state token  of that monad).The associated type % s a links any a/ to the type of its canonical mutable version.The benefit+ of this typeclass, instead of just using  or $ or specific mutable versions like    and  , is two-fold:Piecewise-mutable 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 ' it out. This can be especially useful for composite data types containing large structures like   .!Generic abstractions (similar to ), so you can automatically derive instances while preserving piecewise-ness. For example, the instance 8instance (Mutable s a, Mutable s b) => Mutable s (a, b) If a and b are piecwise-mutable, 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 user-defined instances of .$For example, if we have a type like: 'data TwoVectors = TV { tvInt ::    Int , tvDouble :: Vector Double } deriving Generic instance Mutable s TwoVectors where type Ref s TwoVectors =  s TwoVectors Then now we get: & :: TwoVectors -> m ( s TwoVectors) ' ::  s TwoVectors -> m TwoVectors And  s TwoVectors is now a piecewise-mutable 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  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  TwoVectors. It is also much better for large vectors if you plan on modifying only a single item in the vector.9If you are using the "higher-kinded" data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/, then we can also do: *data TwoVectors f = TV { tvInt ::  f (   Int) , tvDouble :: HKD f (Vector Double) } deriving Generic instance Mutable (TwoVectors !) where type Ref (TwoVectors ) = TwoVectors ( s) And now your mutable ref is literally going to be a product of the components  tvr@(TV is ds) <- thawRef (TV xs ys) ghci> :t tvr TV ( ) ghci> :t is  7 RealWorld Int ghci> :t ds MV.MVector RealWorld Double So & 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 ' 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 %: =-- Make a mutable version for any newtype wrapper, using the $ -- of the underlying type newtype MyType = MT (Vector Double) type Ref s MyType = CoerceRef s 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 s (MyContainer a) = TraverseRef s MyContainer a See  .https://mutable.jle.im/02-mutable-and-ref.html for more information on this typeclass and how to define instances automatically, and also ,https://mutable.jle.im/05-mutable-parts.html6 for more information on dealing with record types *https://mutable.jle.im/06-mutable-branches3 for more information on dealing with sum types%mutableLinks the type a0 to the type of its canonical "mutable version".For example, for   , the mutable version is   , so we have  type Ref s (   a) =   s a This means that using & on a    will give you an  , using ' on a    will give you a   , etc. & :: ( m,  m ~ s) =>    a -> m (   s a) ' :: ( m,  m ~ s) =>    s a -> m (   a) ( :: ( m,  m ~ s) =>    s a ->    a -> m () (This associated type must be unique for a, so no two types a can have the same % s a<. This makes type inference a lot more useful: if you use ' on an  8, for instance, the return type will be inferred to be   .The default instance is just a plain old  containing the type. This is a valid instance, but it treats the entire type "wholesale" --- it is basically using it as a non-mutable type. You won't get any of the performance benefits of piecewise mutation from it, but it is useful as a base case for non-composite types like .There are some built-in alternative options for user-defined ADTs with  instances: -- Works for all  instances, preserves piecewise mutation -- for products type Ref s a =  s a =If you just set up a blank instance, the implementations of &, ', and ( will be inferred using . data MyType -- The default setup is OK instance Mutable s MyType -- This is equivalent to the above instance Mutable s MyType type Ref s MyType =  s MyType -- any  instance data MyType = MyType { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable s MyType where type Ref s MyType =  s MyType See  .https://mutable.jle.im/02-mutable-and-ref.html for more information on this type family and how to define instances automatically.&mutableThaw a pure/persistent value into its mutable version, which can be manipulated using 0 or other methods specific for that type (like  ). Returns the % instance, so, for example, for   : & :: ( m,  m ~ s) =>    a -> m (   s a) For non-composite (like 6), this is often called the "new var" function, like  /  /  etc.'mutableFreeze2 a mutable value into its pure/persistent version.Takes a % instance, but type inference will be able to infer the pure value's type because % is injective.For example, for   : ' :: ( m,  m ~ s) =>    s a -> m (   a) For non-composite (like 7), this is often called the "read var" function, like  /  /  etc.(mutableOverwrite a mutable value by provivding a pure/persistent value. ( Returns the %% and the value, so, for example, for   : ( :: ( m,  m ~ s) =>    s a ->    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 non-composite (like 8), this is often called the "write var" function, like  /  /  etc.)mutableDeep Copy-move a mutable reference on top of another, overwriting the second one./For non-composite types, this is the same as a & and a (. For composite types this can be more effficient because the copying is done piecewise, so the intermediate pure value is never created.*mutableCreate a deep copy of a mutable reference, allocated to a separate independent reference./For non-composite types, this is the same as a & and a '. For composite types this can be more effficient because the cloning is done piecewise, so the intermediate pure value is never created.+mutableA non-copying version of & that can be more efficient for types where the mutable representation is the same as the immutable one (like   ).This is safe as long as you never again use the original pure value, since it can potentially directly mutate it.,mutableA non-copying version of ' that can be more efficient for types where the mutable representation is the same as the immutable one (like   ).This is safe as long as you never again modify the mutable reference, since it can potentially directly mutate the frozen value magically.-mutableDefault & for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information..mutableDefault ' for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information./mutableDefault ( for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information.0mutableDefault ) for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information.1mutableDefault * for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information.2mutableDefault + for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information.3mutableDefault , for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  m f a0 just as a normal data type, independent of the % class. See documentation for  for more information.4mutableDefault & for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.5mutableDefault ' for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.6mutableDefault ( for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.7mutableDefault ) for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.8mutableDefault * for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.9mutableDefault + for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.:mutableDefault , for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.;mutableDefault & for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.<mutableDefault ' for . This will always return the originally thawed value, ignoring all copies and writes.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.=mutableDefault ( for . This is a no-op and does nothing, since freezing will always return the originally thawed value.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.mutableDefault ) for . This is a no-op and does nothing, since freezing will always return the originally thawed value.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.mutableDefault * for . '8 on this value will return the originally thawed value.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s b a1 just as a normal data type, independent of the % class. See documentation for  for more information.>mutableDefault & for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.?mutableDefault ' for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.@mutableDefault ( for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.AmutableDefault ) for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.BmutableDefault * for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.CmutableDefault + for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.DmutableDefault , for .You likely won't ever use this directly, since it is automatically provided if you have a $ instance with  as the %0. However, it can be useful if you are using a  s a1 just as a normal data type, independent of the % class. See documentation for  for more information.EmutableDefault &+ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.FmutableDefault '+ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.GmutableDefault (+ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.HmutableDefault )+ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.ImutableDefault *+ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.JmutableDefault ++ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.KmutableDefault ,+ for the higher-kinded data pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/.You likely won't ever use this directly, since it is automatically provided if you have a $ instance with z ( s) as the %0. However, it can be useful if you are using a z ( s)1 just as a normal data type, independent of the % class. See documentation for $ for more information.mutableUse a  m a as if it were a % s a.mutableUse a  s f a as if it were a f (% s a)mutableUse a  s b a as if it were a % s amutableUse a  a as if it were an a(mutabledestination to overwritemutablevalue)mutable destinationmutablesource0mutable destinationmutablesource  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK(c) Justin Le 2020BSD3 justin@jle.im experimental non-portableNone'(./2567>?s LmutableThe mutable reference of the  type from generic-lens.OmutableUseful type family to % m% over every item in a type-level list ghci> :kind! MapRef IO '[Int, V.Vector Double] '[ MutVar RealWorld Int, MVector RealWorld Double ] Pmutable% for components in a vinyl .VmutableA % of a tuple is a tuple of %s, for easy accessing.WmutableA % of a tuple is a tuple of %s, for easy accessing.XmutableA % of a tuple is a tuple of %s, for easy accessing.YmutableA % of a tuple is a tuple of %s, for easy accessing.  Ref s (Int,  Double) = ( s Int,  s Double) ^mutableMutable reference is ._mutableMutable reference is .`mutableMutable reference is .amutableMutable reference is .bmutable5Meant for usage with higher-kinded data pattern (See )cmutableMutable linked list with mutable references in each cell. See  documentation for an example of using this as a mutable linked list.l= -./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU=PQRLMNSTU>?@ABCDEFGHIJK456789:-./0123;<= ON5(c) Justin Le 2020BSD3 justin@jle.im experimental non-portableNone'(./5678>?%mutable Similar to *, this allows you to overwrite the normal $ instance of a type to make it  immutable.For example, let's say you have a type, with the automatically derived generic instance of $: data MyType = MT { mtX :: Int , mtY :: Vector Double , mtZ :: String } deriving Generic instance Mutable s MyType where type Ref s MyType = GRef s MyType 2This basically uses three mutable references: the , the    Double , and the . However, you might want the $ instance of MyType to be  immutable  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 ::  String } deriving Generic instance Mutable s MyType where type Ref s MyType = GRef s MyType which has that behavior. The  and the    will be mutable within % s MyType, but not the .mutable Similar to *, this allows you to overwrite the normal $3 instance of a type to utilize a coercible type's $ 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   s $ instance (via  6), but you don't want to write an orphan instance like ,instance Mutable s DoubleVec where type % s DoubleVec =  s DoubleVec (Vector Double) then you can instead use  DoubleVec (Vector Double)' as the data type. This wrapped type does use the inderlying $ insatnce for   .mutable Similar to *, this allows you to overwrite the normal $% instance for a type to utilize its  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 $ ( [] a) is a normal list of mutable references, instead of a full-on mutable linked list.mutable1Newtype wrapper that can provide any type with a $ instance, giving it a "non-piecewise" instance. Can be useful for avoiding orphan instances yet still utilizing auto-deriving features, or for overwriting the $ instance of other instances.For example, let's say you want to auto-derive an instance for your data type: 9data MyType = MT Int Double OtherType deriving Generic This is possible if all of MyTypes fields have $ 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 $0 instance without incurring an orphan instance.One solution is to wrap it in : data MyType = MT Int Double ( OtherType) deriving Generic This can then be auto-derived: instance Mutable s MyType where type Ref s MyType = GRef s MyType It can also be used to override a $& instance. For example, even if the $ instance of SomeType is piecewise-mutable, the $ instance of  SomeType will be not be piecewise.For example, the $ instance for  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 $ instance.mutableApply a pure function on an immutable value onto a value stored in a mutable reference.mutable, but forces the result before storing it back in the reference.mutableApply a monadic function on an immutable value onto a value stored in a mutable reference. Uses (3 into the reference after the action is completed.mutable, but forces the result before storing it back in the reference.mutableApply a pure function on an immutable value onto a value stored in a mutable reference, returning a result value from that function.mutable, but forces the updated value before storing it back in the reference.mutableApply a monadic function on an immutable value onto a value stored in a mutable reference, returning a result value from that function. Uses (2 into the reference after the action is completed.mutable, but forces the updated value before storing it back in the reference.mutableA default implementation of ( using & and ).mutableA default implementation of )0 that round-trips through the pure type, using ' and (. It freezes the entire source and then re-copies it into the destination.mutableA default implementation of )0 that round-trips through the pure type, using ' and &. It freezes the entire source and then re-copies it into the destination.mutableUse a  a as if it were an a.mutableUse a  f a as if it were an f amutableUse a  s a as if it were an smutableUse an  a as if it were an amutabledestination to overwritemutable pure valuemutable destinationmutablesource, !"#$%&'()*+,O,$%&'()*+, !"#O(c) Justin Le 2020BSD3 justin@jle.im experimental non-portableNone'(./8>?!mutableTypeclass powering  using GHC Generics.Heavily inspired by Data.Generics.Sum.Constructors.mutable A version of   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.mutableA  s b a! represents the information that b could potentially be an a. Similar in spirit to a  Prism' b a. s b a means that a is one potential option that b could be in, or that b is a sum type and a& is one of the branches/constructors.See  /https://mutable.jle.im/06-mutable-branches.html% for an introduction to this module.If ! is for product types, then  is for sum types.In this case, "branch" means "potential option". For example, the branches of  are  and .+The simplest way to make these is by using 0. For instance, to get the two branches of an : constrMB #_Left :: MutBranch s (Either a b) a constrMB #_Right :: MutBranch s (Either a b) b   ghci> r <- & (Left 10) ghci>  ( #_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 :  ghci> r <- & (Just 10) ghci>  (constrMB #_Just) $ i -> -- i/ is an Int ref .. modifyRef i (+ 1) ghci> ' 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 s a => $, s (List a) where type Ref s (List a) =  s (List a)  s (List a)2 is now a mutable linked list! Once we make the  for the nil and cons cases: nilBranch :: MutBranch s (List a) () nilBranch = constrMB #_Nil consBranch :: MutBranch s (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 s a) => Ref s (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 s a) => Ref s (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 s a) => Ref s (List a) -> Ref s (List a) -> m () concatLists l1 l2 = do c <- projectBranch consBranch l1 case c of Nothing -> moveRef l1 l2 Just (_, xs) -> concatLists xs l2 mutableWith a , attempt to get the mutable contents of a branch of a mutable s, if possible. ghci> r <- thawRef (Left 10) ghci> s <- projectBranch (constrMB #_Left) r ghci> case s of Just s' -> freezeRef s' 10 ghci> r <- thawRef (Right True) ghci> s <- projectBranch (constrMB #_Left) r ghci> case s of Nothing -> "it was Right" "it was Right" mutable Embed an a ref as a part of a larger s ref. Note that this does not copy or clone: any mutations to the a ref will be reflected in the s ref, as long as the s ref maintains the reference. ghci> r <- thawRef 100 ghci> s <- embedBranch (constMB #_Left) r ghci> freezeRef s Left 100 ghci> modifyRef r (+ 1) ghci> freezeRef s Left 101 Any mutations on s: (as long as they keep the same branch) will also affect a: -ghci> copyRef s (Left 0) ghci> freezeRef r 0 $However, "switching branches" on an 4 ref will cause it to loose the original reference: ghci> copyRef s (Right True) ghci> copyRef s (Left 999) ghci> freezeRef r 0 mutable Compose two *s, to drill down on what is being focused.mutable An identity /, treating the item itself as a whole branch.  will always "match".mutableWith a  , thaw an a into a mutable s on that branch.  ghci> r <-  ( #_Left) 10 ghci> ' r Left 10 mutableWith a , read out a specific a branch of an s, if it exists.  ghci> r <- & (Left 10) ghci>  ( #_Left) r Just 10 ghci> freezeBranch (constrMB #_Right) r Nothing mutable Check if an s is currently a certain branch a.mutable Check if an s is not currently a certain branch a.mutableWith a , set s to have the branch a.  ghci> r <- & (Left 10) ghci>  ( #_Left) r 5678 ghci> ' r Left 5678 ghci> copyBranch (constrMB #_Right) r True ghci> freezeRef r Right True mutableWith a , 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 mutableWith a ., 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" mutableA non-copying version of  that can be more efficient for types where the mutable representation is the same as the immutable one (like   ).This is safe as long as you never again modify the mutable reference, since it can potentially directly mutate the frozen value magically.mutableA non-copying version of  that can be more efficient for types where the mutable representation is the same as the immutable one (like   ).This is safe as long as you never again use the original pure value, since it can potentially directly mutate it.mutableWith a , 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 <- & (Just 10) ghci>  ( #_Just) $ i -> -- i is an Int ref ..  i (+ 1) ghci> ' 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$, but discarding the returned value.mutableWith a ., run a pure function over a potential branch a of s. If s is not on that branch, leaves s unchanged.  ghci> r <- & (Just 10) ghci>  (+ #_Just) r (+ 1) ghci> freezeRef r Just 11 ghci> r <- thawRef Nothing ghci> modifyBranch (constrMB #_Just) r (+ 1) ghci> freezeRef r Nothing mutable, but forces the result before storing it back in the reference.mutable# but for a monadic function. Uses (3 into the reference after the action is completed.mutable, but forces the result before storing it back in the reference.mutableWith a ., 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 <- & (Just 10) ghci>  (2 #_Just) r $ i -> (i + 1, show i) Just "10" ghci> ' r Just 11 ghci> r <- thawRef Nothing ghci> updateBranch (constrMB #_Just) r $ i -> (i + 1, show i) Nothing ghci> freezeRef r Nothing mutable, but forces the result before storing it back in the reference.mutable# but for a monadic function. Uses (3 into the reference after the action is completed.mutable, but forces the result before storing it back in the reference.mutable Create a  for any data type with a  instance by specifying the constructor name using OverloadedLabels  ghci> r <- & (Left 10) ghci>  ( #_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: -- |  focusing on the cons case of a list consMB :: (PrimMonad m, Mutable s a) => MutBranch s [a] (a, [a]) consMB =  ( @":") mutable# focusing on the nil case of a listmutable$ focusing on the cons case of a listmutable focusing on the  case of a mutable focusing on the  case of a mutable focusing on the  case of an mutable focusing on the  case of an mutableHow to check if is s is an amutableStructure to read out ofmutableHow to check if s is an amutableStructure to write intomutable Value to set s to bemutableHow to check if s is an amutableStructure to read out ofmutableHow to check if is s is an amutableStructure to read out ofmutableHow to check if is s is an amutable'Structure to read out of and write intomutableAction to perform on the a branch of smutableHow to check if is s is an amutable'Structure to read out of and write intomutableAction to perform on the a branch of smutableHow to check if s is an amutable'Structure to read out of and write intomutablePure function modifying amutableHow to check if s is an amutable'Structure to read out of and write intomutablePure function modifying amutableHow to check if s is an amutable'Structure to read out of and write intomutableMonadic function modifying amutableHow to check if s is an amutable'Structure to read out of and write intomutableMonadic function modifying amutableHow to check if s is an amutable'Structure to read out of and write intomutableHow to check if s is an amutable'Structure to read out of and write intomutableHow to check if s is an amutable'Structure to read out of and write intomutableHow to check if s is an amutable'Structure to read out of and write into$O$O(c) Justin Le 2020BSD3 justin@jle.im experimental non-portableNone'(./>?&mutableFor products, we first traverse the left-hand side, followed by the second using the counter returned by the left traversal.mutable Create a  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 . See  for usage directions.Mostly leverages the power of Data.Generics.Product.HList.mutable Create a  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 . Probably most easily used using : data MyType = MyType Int Double deriving (Generic, Show) instance Mutable s MyType where type Ref s MyType =  s MyType Now there is an instance of  m MyType (Int, Double).  ghci> r <- & (MyType 3 4.5) ghci>  r $ (rI, rD) -> do .. . rI negate .. modifyRef rD (* 2) ghci> ' r MyType (-3) 9 As can be seen, within the lambda, we can get access to every mutable reference inside a MyType reference.1Performance-wise, this appears to be faster than  and  when using a single reference, but slower if using all references.mutable Create a  for a position in a product type. Should work for any type with one constructor whose mutable reference is . See  for usage directions.Mostly leverages the power of Data.Generics.Product.Positions.mutable Create a  for a position in a product type. Should work for any type with one constructor whose mutable reference is .'Meant to be used with TypeApplications: data MyType = MyType Int Double deriving (Generic, Show) instance Mutable s MyType where type Ref s MyType =  s MyType   ghci> r <- & (MyType 3 4.5) ghci>  ( @1) r 3 ghci>  (posMut @2) 1.23 ghci> ' r MyType 3 1.23  This and ! are the main ways to generate a ( for a type whose mutable reference is . Note that because all of the lookups are done at compile-time,  and : have more or less identical performance characteristics.mutable Create a  for a field name. Should work for any type with one constructor whose mutable reference is . See  for usage directions.Mostly leverages the power of Data.Generics.Product.Fields.mutable Create a  for a field name. Should work for any type with one constructor whose mutable reference is .*Is meant to be used with OverloadedLabels: data MyType = MyType { mtInt :: Int, mtDouble :: Double } deriving (Generic, Show) instance Mutable s MyType where type Ref s MyType =  s MyType   ghci> r <- & (MyType 3 4.5) ghci>  ( #mtInt) r 3 ghci> ! (fieldMut #mtDouble) 1.23 ghci> ' r MyType 3 1.23 :However, you can use it without OverloadedLabels by using  with TypeApplications: ghci>  ( ( @"mtInt")) r 3  This and ! are the main ways to generate a ( for a type whose mutable reference is . Note that because all of the lookups are done at compile-time,  and : have more or less identical performance characteristics.mutableTypeclass used to implement . See documentation of  for more information.mutableA  s b a is a way to "zoom into" an a', as a part of a mutable reference on b,. This allows you to only modify a single a part of the b=, without touching the rest. It's spiritually similar to a  Lens' b a.If  is for sum types, then  is for product types.See  ,https://mutable.jle.im/05-mutable-parts.html# for an introduction to this type.An example that is commonly found in the ecosystem is something like (flipped) write :: Int -> " s a -> a -> m () from Data.Vector.Mutable ---  write 3 :: " s a -> a -> m (), for instance, lets you modify a specific part of the vector without touching the rest. You would use a  using , , , etc.For non-composite types, there won't really be any meaningful values. However, we have them for many composite types. For example, for tuples:  ::  s (a, b) a  :: MutPart s (a, b) b   ghci> r <- & (2, 4) ghci>  mutFst r 100 ghci> ' r (100, 4) If you are using  as an automatically-defined mutable reference, then the easiest way to create these for your mutable types are with  and .If you are using the "Higher-kinded data" pattern, then there's an easy way to generate a = for every single field, if you have a product type --- see  for more information.mutable Compose two s one after the other.Note this is also available (albeit flipped in arguments) through the  instance.mutable The identity ): simply focus into the same type itself.(Note this is also available through the  instance.mutable+ into the first field of a tuple reference.mutable, into the second field of a tuple reference.mutableUsing a , perform a function on a % s s as if you had a % s a.mutableWith a  , read out a specific part of a %.mutableWith a &, overwrite into a specific part of a %.mutableWith a  , copy a %9 containing a subvalue into a specific part of a larger %. data MyType = MT { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable s MyType where type Ref s MyType = GRef s 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 mutableWith a #, copy a specific part of a larger % into a % of the smaller subvalue value. data MyType = MT { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable s MyType where type Ref s MyType = GRef s MyType ghci> x <- thawRef $ MyType 3 4.5 ghci> y <- thawRef $ 100 ghci> movePartOver (fieldMut #mtInt) y x ghci> freezeRef y 3 mutableWith a ", copy a specific part of a large %' into that same part in another large %. data MyType = MT { mtInt :: Int, mtDouble :: Double } deriving Generic instance Mutable s MyType where type Ref s MyType = GRef s 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 mutable!Clone out a subvalue of a larger %.mutableA non-copying version of , that can be more efficient for types where the mutable representation is the same as the immutable one (like   ).This is safe as long as you never again modify the mutable reference, since it can potentially directly mutate the frozen value magically.mutableWith a , modify a specific part of a % with a pure function.mutable, but forces the result before storing it back in the reference.mutable , under a & to only modify a specific part of a %.mutable, but forces the result before storing it back in the reference.mutableWith a , modify a specific part of a %! with a monadic function. Uses (3 into the reference after the action is completed.mutable, but forces the result before storing it back in the reference.mutable , under a & to only modify a specific part of a %. (2 into the reference after the action is completed.mutable, but forces the result before storing it back in the reference.mutableA  for a field in a vinyl , automatically generated as the first field with a matching type. This is polymorphic to work over both  and .  ghci> r <- & $ [1,2,3]  # [True, False] :&  $ ghci> modifyPart (mutRec @Bool) r reverse ghci> freezeRef r [1,2,3] :& [False, True] :& RNil mutableA  to get into a .mutableHandy wrapper over  .mutable9If you are using the "higher-kinded data" pattern, a la  :https://reasonablypolymorphic.com/blog/higher-kinded-data/-, and you have the appropriate instance for %', then you can use this to generate a  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 (MyTypeF ) where type Ref (MyTypeF  ) = MyTypeF () m) mx :: MutPart s (MyTypeF Identity) (   Int) my :: MutPart s (MyTypeF Identity) (Vector Double) MT mx my = hkdMutParts @MyTypeF  $ghci> r <- thawRef (MT 3 4.5) ghci>  mx r 3 ghci> 0 (mtDouble (hkdMutParts @MyTypeF)) r 12.3 ghci> ' r MT 3 12.3 .Performance-wise, this is about equivalent to  and  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  and 5, but immediate shallow access is often faster with 8...but this probably does vary on a case-by-case basis.mutableA helpful wrapper over  ( #blah) . Create a  and directly use it.mutableA helpful wrapper around  ( #blah). Directly use a  to access a mutable field.mutableA helpful wrapper over  ( @n) . Create a  and directly use it.mutableA helpful wrapper around  ( @n). Directly use a  to access a mutable field.mutableA helpful wrapper over  . Directly operate on the items in the data type, getting the references as a tuple. See + for more details on when this should work. data MyType = MyType Int Double deriving (Generic, Show) instance Mutable s MyType where type Ref s MyType =  s MyType  ghci> r <- & (MyType 3 4.5) ghci>  r $ (rI, rD) -> do .. . rI negate .. modifyRef rD (* 2) ghci> ' r MyType (-3) 9 mutable:field label (usually given using OverloadedLabels, @#blah)mutableHow to zoom into an a from an smutableThe larger reference of smutable-What do do with the smaller sub-reference of amutablebigger type (destination)mutablesmaller type (source)mutablesmaller type (destination)mutablebigger type (source)mutable destinationmutablesourcemutable:field label (usually given using OverloadedLabels, @#blah)mutableLarger record referencemutable!What to do with the mutable fieldmutable:field label (usually given using OverloadedLabels, @#blah)mutableLarger record referencemutableInternal mutable fieldmutableLarger record referencemutable!What to do with the mutable fieldmutableLarger record referencemutableInternal mutable fieldmutableLarger record referencemutable*What to do with each mutable field. The % s a& will be a tuple of every field's ref.*O*O9 (c) Justin Le 2020BSD3 justin@jle.im experimental non-portableNone $%&'()*+,LMNOPQRSTU$%&'()*+, PQRLMNSTUO%%&'%&() ) **+,,-../01223445667889:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnnoppqrstuvwxyz{|}~  !! ))%%%)" )mutable-0.2.0.0-inplace Data.MutableData.Mutable.PartsData.Mutable.InstancesData.Mutable.ClassData.Mutable.BranchesData.Mutable.Internal freezePartfieldMutcopyPart ImmutableVVectorMVMVector Data.IORefIORef modifyRefreadnewIORef Data.STRefnewSTRef readIORef readSTRef writeIORef writeSTRefData.Primitive.MutVarMutVarXHKD MutBranchData.Vinyl.DerivedLabelMutPart Data.Vector:&RNilprimitive-0.7.1.0-e67c5957d2d87e4027feaf8b0636ea7c89b56239a10b1c00f1e24d2d2cdfb61bControl.Monad.Primitive PrimState PrimMonadvinyl-0.12.3-4d0bba86a28148cdb33aa925dec46eae0da65ff3c15d549f4b7ddbbd8504f01aGRefunGRef GMutableRefgetGMutableRefMutSumF getMutSumFGMutableGRef_ ImmutableRefgetImmutableRef CoerceRef getCoerceRef TraverseRefgetTraverseRefRefFor getRefForDefaultMutabledefaultThawRefdefaultFreezeRefdefaultCopyRefdefaultMoveRefdefaultCloneRefdefaultUnsafeThawRefdefaultUnsafeFreezeRefMutableRefthawRef freezeRefcopyRefmoveRefcloneRef unsafeThawRefunsafeFreezeRef thawTraversefreezeTraverse copyTraverse moveTraverse cloneTraverseunsafeThawTraverseunsafeFreezeTraverse thawCoerce freezeCoerce copyCoerce moveCoerce cloneCoerceunsafeThawCoerceunsafeFreezeCoerce thawImmutablefreezeImmutable copyImmutablegThawRef gFreezeRefgCopyRefgMoveRef gCloneRefgUnsafeThawRefgUnsafeFreezeRefthawHKD freezeHKDcopyHKDmoveHKDcloneHKD unsafeThawHKDunsafeFreezeHKDHListRefNilRef:!>MapRefRecRef getRecRefUnitRefVoidRef$fMutables(,,,,)$fMutables(,,,)$fMutables(,,) $fMutables(,)$fMutablesPrimArray$fMutablesByteArray$fMutablesSmallArray$fMutablesArray$fMutablesVector$fMutablesVector0$fMutablesVector1$fMutablesVector2$fMutablesIdentity $fMutables[]$fMutablesCompose $fMutablesSum$fMutablesProduct$fMutablesEither$fMutablesMaybe$fMutablesDual$fMutablesDown$fMutablesSum0$fMutablesProduct0$fMutablesConst$fMutablesConst0$fMutablesIdentity0$fMutablesCDouble$fMutablesCFloat$fMutablesCSUSeconds$fMutablesCUSeconds$fMutablesCTime$fMutablesCClock$fMutablesCUIntMax$fMutablesCIntMax$fMutablesCUIntPtr$fMutablesCIntPtr$fMutablesCBool$fMutablesCULLong$fMutablesCLLong$fMutablesCSigAtomic$fMutablesCWchar$fMutablesCSize$fMutablesCPtrdiff$fMutablesCULong$fMutablesCLong$fMutablesCUInt$fMutablesCInt$fMutablesCUShort$fMutablesCShort$fMutablesCUChar$fMutablesCSChar$fMutablesCChar$fMutablesWord64$fMutablesWord16$fMutablesWord8$fMutablesWord$fMutablesChar$fMutablesBool$fMutablesComplex$fMutablesDouble$fMutablesFloat$fMutablesRatio$fMutablesNatural$fMutablesInteger $fMutablesInt$fMutablesVoid $fMutables()$fMonadUnitRef$fApplicativeUnitRef$fMutablesARec $fMutablesRec$fMutablesRec0$fMutablesHList$fMutablesHList0 $fShowUnitRef $fReadUnitRef $fEqUnitRef $fOrdUnitRef$fFunctorUnitRef$fTraversableUnitRef$fFoldableUnitRef $fShowVoidRef $fReadVoidRef $fEqVoidRef $fOrdVoidRef$fFunctorVoidRef$fTraversableVoidRef$fFoldableVoidRef $fOrdRecRef $fEqRecRef getImmutable CoerceMut getCoerceMut TraverseMutgetTraverseMutVarMut getVarMut modifyRef' modifyRefM modifyRefM' updateRef updateRef' updateRefM updateRefM' copyRefWhole moveRefWhole cloneRefWhole$fMutablesVarMut$fIsoHKDTYPEVarMuta$fMutablesTraverseMut$fIsoHKDkTraverseMuta$fMutablesCoerceMut$fIsoHKDkCoerceMuta$fMutablesImmutable$fIsoHKDTYPEImmutablea$fShowTraverseMut$fEqTraverseMut$fOrdTraverseMut$fGenericTraverseMut$fFunctorTraverseMut$fFoldableTraverseMut$fTraversableTraverseMutGMutBranchConstructorCLabel projectBranch embedBranchcompMBidMB thawBranch freezeBranch hasBranch hasn'tBranch copyBranch moveBranch cloneBranchunsafeFreezeBranchunsafeThawBranch withBranch withBranch_ modifyBranch modifyBranch' modifyBranchMmodifyBranchM' updateBranch updateBranch' updateBranchMupdateBranchM'constrMBnilMBconsMB nothingMBjustMBleftMBrightMB$fIsLabelctor_CLabel$fGMutBranchConstructorctormM1a $fGMutBranchConstructorctors:+:a$fListRefTuples(,):$fListRefTuplesra:$fListRefTuplesUnitRef[]$fGMutBranchSumctorFalseslra$fGMutBranchSumctorTrueslra$fGMutBranchConstructorctorsM1aTupleMuttupleMutPosMutposMutFieldMut HKDMutParts getMutPartcompMPidMPmutFstmutSndwithPart movePartInto movePartOvermovePartWithin clonePartunsafeFreezePart modifyPart modifyPart' updatePart updatePart' modifyPartM modifyPartM' updatePartM updatePartM'mutRec coerceRef withCoerceRef hkdMutParts withFieldmutFieldwithPosmutPos withTuple$fIsoHKDTYPEMutParta$fCategoryTYPEMutPart$fHKDMutPartsksz:+:o$fHKDMutPartsksz:*::*:$fHKDMutPartskszM1M1$fHKDMutPartskszV1V1$fHKDMutPartskszU1U1$fHKDMutPartskszK1K1$fFieldMutfldsba $fTupleMutsba $fPosMutisbabase GHC.GenericsGeneric:+:Data.Traversable TraversableData.Vinyl.XRecGHC.ShowShowData.Vinyl.FunctorIdentityghc-primGHC.Prim RealWorld GHC.TypesInt newMutVar readMutVar writeMutVar moveImmutablecloneImmutable$fIsoHKDTYPERefFora$fIsoHKDTYPETraverseRefa$fIsoHKDTYPECoerceRefa$fIsoHKDTYPEImmutableRefageneric-lens-core-2.0.0.0-fb3ffb4b4e7b2ce424a9992b17c561aa9cfddde349f566a561817c08e3136e9b$Data.Generics.Product.Internal.HListHListData.Vinyl.CoreRecvector-0.12.1.2-4093acd09fb3b0e60e40cc848e18478a10080ac13a1d3812df085b54ae1d775bData.Vector.MutableData.Vector.Primitive.MutableData.Vector.Unboxed.BaseData.Vector.Storable.MutableGHC.BaseString Data.EitherEitherLeftRight GHC.MaybeNothingMaybeJust TraverseProdControl.CategoryCategoryData.Vinyl.ARecARec