-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Automatic piecewise-mutable references for your types -- -- Associate and generate "piecewise-mutable" versions for your composite -- data types. Think of it like a "generalized MVector for all ADTs". -- -- Useful for a situation where you have a record with many fields (or -- many nested records) that you want to use for efficient mutable -- in-place algorithms. This library lets you do efficient "piecewise" -- mutations (operations that only edit one field), and also efficient -- entire-datatype copies/updates, as well, in many cases. -- -- See https://mutable.jle.im for official introduction and -- documentation, or jump right in by importing Data.Mutable. @package mutable @version 0.2.2.0 -- | Exports Ref data types for various common data types, and also -- the tools for automatic derivation of instances. See -- Data.Mutable for more information. module Data.Mutable.Instances -- | Ref for components in a vinyl Rec. newtype RecRef s f a RecRef :: Ref s (f a) -> RecRef s f a [getRecRef] :: RecRef s f a -> Ref s (f a) -- | The mutable reference of the HList type from generic-lens. data HListRef :: Type -> [Type] -> Type [NilRef] :: HListRef s '[] [:!>] :: Ref s a -> HListRef s as -> HListRef s (a : as) infixr 5 :!> -- | The Ref for () (unit). This breaks the pattern for -- tuple instances (type Ref s (a, b) = (Ref s a, -- Ref s b)), but is necessary for type inference (see -- documentation for Ref). data UnitRef s UnitRef :: UnitRef s -- | The Ref for Void. data VoidRef s -- | Automatically generate a piecewise mutable reference for any -- Generic instance. -- --
--   -- | any Generic instance
--   data MyType = MyType { mtInt :: Int, mtDouble :: Double }
--     deriving (Generic, Show)
--   
--   instance Mutable s MyType where
--       type Ref s MyType = GRef s 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 unGRef @MyType 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. newtype GRef s a GRef :: GRef_ s (Rep a) () -> GRef s a [unGRef] :: GRef s a -> GRef_ s (Rep a) () -- | Default thawRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gThawRef :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => a -> m (GRef s a) -- | Default freezeRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gFreezeRef :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => GRef s a -> m a -- | Default copyRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gCopyRef :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => GRef s a -> a -> m () -- | Default moveRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gMoveRef :: (GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => GRef s a -> GRef s a -> m () -- | Default cloneRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gCloneRef :: (GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => GRef s a -> m (GRef s a) -- | Default unsafeThawRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gUnsafeThawRef :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => a -> m (GRef s a) -- | Default unsafeFreezeRef for GRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with GRef as the -- Ref. However, it can be useful if you are using a -- GRef s a just as a normal data type, independent of -- the Ref class. See documentation for GRef for more -- information. gUnsafeFreezeRef :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s) => GRef s a -> m a -- | Class for automatic generation of Ref for Generic -- instances. See GRef for more information. class GMutable s (f :: Type -> Type) where { type family GRef_ s f = (u :: Type -> Type) | u -> f; } -- | Default thawRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. thawHKD :: forall z m s. (Generic (z Identity), Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z Identity -> m (z (RefFor s)) -- | Default freezeRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. freezeHKD :: forall z m s. (Generic (z Identity), Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z (RefFor s) -> m (z Identity) -- | Default copyRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. copyHKD :: forall z m s. (Generic (z Identity), Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z (RefFor s) -> z Identity -> m () -- | Default moveRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. moveHKD :: forall z m s. (Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z (RefFor s) -> z (RefFor s) -> m () -- | Default cloneRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. cloneHKD :: forall z m s. (Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z (RefFor s) -> m (z (RefFor s)) -- | Default unsafeThawRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. unsafeThawHKD :: forall z m s. (Generic (z Identity), Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z Identity -> m (z (RefFor s)) -- | Default unsafeFreezeRef 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 Mutable instance with z -- (RefFor s) as the Ref. However, it can be useful if -- you are using a z (RefFor s) just as a normal data -- type, independent of the Ref class. See documentation for -- Mutable for more information. unsafeFreezeHKD :: forall z m s. (Generic (z Identity), Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)), PrimMonad m, PrimState m ~ s) => z (RefFor s) -> m (z Identity) -- | 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)
--   
--   instance Mutable s MyVec where
--       type Ref s MyVec = CoerceRef s s (Vector Double)
--   
-- -- The Ref s MyVec uses the a MVector Double -- under the hood. -- -- It's essentially a special case of GRef for newtypes. newtype CoerceRef s b a CoerceRef :: Ref s a -> CoerceRef s b a [getCoerceRef] :: CoerceRef s b a -> Ref s a -- | Default thawRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. thawCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => b -> m (CoerceRef s b a) -- | Default freezeRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. freezeCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> m b -- | Default copyRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. copyCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> b -> m () -- | Default moveRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. moveCoerce :: (Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> CoerceRef s b a -> m () -- | Default cloneRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. cloneCoerce :: (Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> m (CoerceRef s b a) -- | Default unsafeThawRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. unsafeThawCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => b -> m (CoerceRef s b a) -- | Default unsafeFreezeRef for CoerceRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with CoerceRef -- as the Ref. However, it can be useful if you are using a -- CoerceRef s b a just as a normal data type, -- independent of the Ref class. See documentation for -- CoerceRef for more information. unsafeFreezeCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> m b -- | 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 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: -- -- -- --
--   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]
--   
newtype TraverseRef s f a TraverseRef :: f (Ref s a) -> TraverseRef s f a [getTraverseRef] :: TraverseRef s f a -> f (Ref s a) -- | Default thawRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. thawTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => f a -> m (TraverseRef s f a) -- | Default freezeRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. freezeTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> m (f a) -- | Default copyRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. copyTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> f a -> m () -- | Default moveRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. moveTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> TraverseRef s f a -> m () -- | Default cloneRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. cloneTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> m (TraverseRef s f a) -- | Default unsafeThawRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. unsafeThawTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => f a -> m (TraverseRef s f a) -- | Default unsafeFreezeRef for TraverseRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with TraverseRef -- as the Ref. However, it can be useful if you are using a -- TraverseRef m f a just as a normal data type, -- independent of the Ref class. See documentation for -- TraverseRef for more information. unsafeFreezeTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> m (f a) -- | A "Ref" that can be used to give a default Mutable -- instance that is immutable. Nothing is allocated ever, all attempts to -- modify it will be ignored, and freezeRef will just get the -- original thawed value. -- -- Really only exists to be used with Immutable. newtype ImmutableRef s a ImmutableRef :: a -> ImmutableRef s a [getImmutableRef] :: ImmutableRef s a -> a -- | Default thawRef for ImmutableRef. -- -- You likely won't ever use this directly, since it is automatically -- provided if you have a Mutable instance with -- ImmutableRef as the Ref. However, it can be useful if -- you are using a ImmutableRef s b a just as a normal -- data type, independent of the Ref class. See documentation for -- ImmutableRef for more information. thawImmutable :: Applicative m => a -> m (ImmutableRef s a) -- | Default freezeRef for ImmutableRef. 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 Mutable instance with -- ImmutableRef as the Ref. However, it can be useful if -- you are using a ImmutableRef s b a just as a normal -- data type, independent of the Ref class. See documentation for -- ImmutableRef for more information. freezeImmutable :: Applicative m => ImmutableRef s a -> m a -- | Default copyRef for ImmutableRef. 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 Mutable instance with -- ImmutableRef as the Ref. However, it can be useful if -- you are using a ImmutableRef s b a just as a normal -- data type, independent of the Ref class. See documentation for -- ImmutableRef for more information. copyImmutable :: Applicative m => ImmutableRef s a -> a -> m () -- | A Ref for instances of GMutable, which are the -- GHC.Generics combinators. newtype GMutableRef s f a GMutableRef :: GRef_ s f a -> GMutableRef s f a [getGMutableRef] :: GMutableRef s f a -> GRef_ s f a -- | Wraps :+: in a mutable reference. Used internally to represent -- generic sum references. newtype MutSumF s f g a MutSumF :: MutVar s ((f :+: g) a) -> MutSumF s f g a [getMutSumF] :: MutSumF s f g a -> MutVar s ((f :+: g) a) -- | Useful type family to Ref m over every item in a -- type-level list -- --
--   ghci> :kind! MapRef IO '[Int, V.Vector Double]
--   '[ MutVar RealWorld Int, MVector RealWorld Double ]
--   
type family MapRef s as instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc) '[a, b, c] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd) '[a, b, c, d] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re) '[a, b, c, d, e] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf) '[a, b, c, d, e, f] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf, Data.Mutable.Internal.Ref s g GHC.Types.~ rg) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf, rg) '[a, b, c, d, e, f, g] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf, Data.Mutable.Internal.Ref s g GHC.Types.~ rg, Data.Mutable.Internal.Ref s h GHC.Types.~ rh) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf, rg, rh) '[a, b, c, d, e, f, g, h] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf, Data.Mutable.Internal.Ref s g GHC.Types.~ rg, Data.Mutable.Internal.Ref s h GHC.Types.~ rh, Data.Mutable.Internal.Ref s i GHC.Types.~ ri) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf, rg, rh, ri) '[a, b, c, d, e, f, g, h, i] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf, Data.Mutable.Internal.Ref s g GHC.Types.~ rg, Data.Mutable.Internal.Ref s h GHC.Types.~ rh, Data.Mutable.Internal.Ref s i GHC.Types.~ ri, Data.Mutable.Internal.Ref s j GHC.Types.~ rj) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf, rg, rh, ri, rj) '[a, b, c, d, e, f, g, h, i, j] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf, Data.Mutable.Internal.Ref s g GHC.Types.~ rg, Data.Mutable.Internal.Ref s h GHC.Types.~ rh, Data.Mutable.Internal.Ref s i GHC.Types.~ ri, Data.Mutable.Internal.Ref s j GHC.Types.~ rj, Data.Mutable.Internal.Ref s k GHC.Types.~ rk) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk) '[a, b, c, d, e, f, g, h, i, j, k] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb, Data.Mutable.Internal.Ref s c GHC.Types.~ rc, Data.Mutable.Internal.Ref s d GHC.Types.~ rd, Data.Mutable.Internal.Ref s e GHC.Types.~ re, Data.Mutable.Internal.Ref s f GHC.Types.~ rf, Data.Mutable.Internal.Ref s g GHC.Types.~ rg, Data.Mutable.Internal.Ref s h GHC.Types.~ rh, Data.Mutable.Internal.Ref s i GHC.Types.~ ri, Data.Mutable.Internal.Ref s j GHC.Types.~ rj, Data.Mutable.Internal.Ref s k GHC.Types.~ rk, Data.Mutable.Internal.Ref s l GHC.Types.~ rl) => Data.Mutable.Internal.ListRefTuple s (ra, rb, rc, rd, re, rf, rg, rh, ri, rj, rk, rl) '[a, b, c, d, e, f, g, h, i, j, k, l] instance forall k s (f :: k -> *) (a :: k). GHC.Classes.Eq (Data.Mutable.Internal.Ref s (f a)) => GHC.Classes.Eq (Data.Mutable.Instances.RecRef s f a) instance forall k s (f :: k -> *) (a :: k). GHC.Classes.Ord (Data.Mutable.Internal.Ref s (f a)) => GHC.Classes.Ord (Data.Mutable.Instances.RecRef s f a) instance Data.Mutable.Internal.Mutable s (Data.Generics.Product.Internal.HList.HList '[]) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s (Data.Generics.Product.Internal.HList.HList as), Data.Mutable.Internal.Ref s (Data.Generics.Product.Internal.HList.HList as) GHC.Types.~ Data.Mutable.Instances.HListRef s as) => Data.Mutable.Internal.Mutable s (Data.Generics.Product.Internal.HList.HList (a : as)) instance forall u s (f :: u -> *). Data.Mutable.Internal.Mutable s (Data.Vinyl.Core.Rec f '[]) instance forall a1 s (f :: a1 -> *) (a2 :: a1) (as :: [a1]). (Data.Mutable.Internal.Mutable s (f a2), Data.Mutable.Internal.Mutable s (Data.Vinyl.Core.Rec f as), Data.Mutable.Internal.Ref s (Data.Vinyl.Core.Rec f as) GHC.Types.~ Data.Vinyl.Core.Rec (Data.Mutable.Instances.RecRef s f) as) => Data.Mutable.Internal.Mutable s (Data.Vinyl.Core.Rec f (a2 : as)) instance forall k (as :: [k]) s (f :: k -> *). (Data.Vinyl.Core.RecApplicative as, Data.Vinyl.TypeLevel.NatToInt (Data.Vinyl.TypeLevel.RLength as), Data.Vinyl.Core.RPureConstrained (Data.Vinyl.ARec.IndexableField as) as, Data.Mutable.Internal.Mutable s (Data.Vinyl.Core.Rec f as), Data.Mutable.Internal.Ref s (Data.Vinyl.Core.Rec f as) GHC.Types.~ Data.Vinyl.Core.Rec (Data.Mutable.Instances.RecRef s f) as) => Data.Mutable.Internal.Mutable s (Data.Vinyl.ARec.ARec f as) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c) => Data.Mutable.Internal.Mutable s (a, b, c) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d) => Data.Mutable.Internal.Mutable s (a, b, c, d) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e) => Data.Mutable.Internal.Mutable s (a, b, c, d, e) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f, Data.Mutable.Internal.Mutable s g) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f, g) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f, Data.Mutable.Internal.Mutable s g, Data.Mutable.Internal.Mutable s h) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f, g, h) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f, Data.Mutable.Internal.Mutable s g, Data.Mutable.Internal.Mutable s h, Data.Mutable.Internal.Mutable s i) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f, g, h, i) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f, Data.Mutable.Internal.Mutable s g, Data.Mutable.Internal.Mutable s h, Data.Mutable.Internal.Mutable s i, Data.Mutable.Internal.Mutable s j) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f, g, h, i, j) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f, Data.Mutable.Internal.Mutable s g, Data.Mutable.Internal.Mutable s h, Data.Mutable.Internal.Mutable s i, Data.Mutable.Internal.Mutable s j, Data.Mutable.Internal.Mutable s k) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f, g, h, i, j, k) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s c, Data.Mutable.Internal.Mutable s d, Data.Mutable.Internal.Mutable s e, Data.Mutable.Internal.Mutable s f, Data.Mutable.Internal.Mutable s g, Data.Mutable.Internal.Mutable s h, Data.Mutable.Internal.Mutable s i, Data.Mutable.Internal.Mutable s j, Data.Mutable.Internal.Mutable s k, Data.Mutable.Internal.Mutable s l) => Data.Mutable.Internal.Mutable s (a, b, c, d, e, f, g, h, i, j, k, l) instance Data.Mutable.Internal.ListRefTuple s (Data.Mutable.Instances.UnitRef s) '[] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra) => Data.Mutable.Internal.ListRefTuple s ra '[a] instance (Data.Mutable.Internal.Ref s a GHC.Types.~ ra, Data.Mutable.Internal.Ref s b GHC.Types.~ rb) => Data.Mutable.Internal.ListRefTuple s (ra, rb) '[a, b] instance Data.Foldable.Foldable Data.Mutable.Instances.UnitRef instance Data.Traversable.Traversable Data.Mutable.Instances.UnitRef instance GHC.Base.Functor Data.Mutable.Instances.UnitRef instance forall k (s :: k). GHC.Classes.Ord (Data.Mutable.Instances.UnitRef s) instance forall k (s :: k). GHC.Classes.Eq (Data.Mutable.Instances.UnitRef s) instance forall k (s :: k). GHC.Read.Read (Data.Mutable.Instances.UnitRef s) instance forall k (s :: k). GHC.Show.Show (Data.Mutable.Instances.UnitRef s) instance Data.Foldable.Foldable Data.Mutable.Instances.VoidRef instance Data.Traversable.Traversable Data.Mutable.Instances.VoidRef instance GHC.Base.Functor Data.Mutable.Instances.VoidRef instance forall k (s :: k). GHC.Classes.Ord (Data.Mutable.Instances.VoidRef s) instance forall k (s :: k). GHC.Classes.Eq (Data.Mutable.Instances.VoidRef s) instance forall k (s :: k). GHC.Read.Read (Data.Mutable.Instances.VoidRef s) instance forall k (s :: k). GHC.Show.Show (Data.Mutable.Instances.VoidRef s) instance GHC.Base.Applicative Data.Mutable.Instances.UnitRef instance GHC.Base.Monad Data.Mutable.Instances.UnitRef instance Data.Mutable.Internal.Mutable s () instance Data.Mutable.Internal.Mutable s Data.Void.Void instance Data.Mutable.Internal.Mutable s GHC.Types.Int instance Data.Mutable.Internal.Mutable s GHC.Integer.Type.Integer instance Data.Mutable.Internal.Mutable s GHC.Natural.Natural instance Data.Mutable.Internal.Mutable s (GHC.Real.Ratio a) instance Data.Mutable.Internal.Mutable s GHC.Types.Float instance Data.Mutable.Internal.Mutable s GHC.Types.Double instance Data.Mutable.Internal.Mutable s (Data.Complex.Complex a) instance Data.Mutable.Internal.Mutable s GHC.Types.Bool instance Data.Mutable.Internal.Mutable s GHC.Types.Char instance Data.Mutable.Internal.Mutable s GHC.Types.Word instance Data.Mutable.Internal.Mutable s GHC.Word.Word8 instance Data.Mutable.Internal.Mutable s GHC.Word.Word16 instance Data.Mutable.Internal.Mutable s GHC.Word.Word64 instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CChar instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CSChar instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CUChar instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CShort instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CUShort instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CInt instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CUInt instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CLong instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CULong instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CPtrdiff instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CSize instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CWchar instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CSigAtomic instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CLLong instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CULLong instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CBool instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CIntPtr instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CUIntPtr instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CIntMax instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CUIntMax instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CClock instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CTime instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CUSeconds instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CSUSeconds instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CFloat instance Data.Mutable.Internal.Mutable s Foreign.C.Types.CDouble instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Functor.Identity.Identity a) instance forall k s a (b :: k). Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Functor.Const.Const a b) instance forall k s a (b :: k). Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Vinyl.Functor.Const a b) instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Semigroup.Internal.Product a) instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Semigroup.Internal.Sum a) instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Ord.Down a) instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Semigroup.Internal.Dual a) instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (GHC.Maybe.Maybe a) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b) => Data.Mutable.Internal.Mutable s (Data.Either.Either a b) instance forall k s (f :: k -> *) (a :: k) (g :: k -> *). (Data.Mutable.Internal.Mutable s (f a), Data.Mutable.Internal.Mutable s (g a)) => Data.Mutable.Internal.Mutable s (Data.Functor.Product.Product f g a) instance forall k s (f :: k -> *) (a :: k) (g :: k -> *). (Data.Mutable.Internal.Mutable s (f a), Data.Mutable.Internal.Mutable s (g a)) => Data.Mutable.Internal.Mutable s (Data.Functor.Sum.Sum f g a) instance forall k k1 s (f :: k -> *) (g :: k1 -> k) (a :: k1). Data.Mutable.Internal.Mutable s (f (g a)) => Data.Mutable.Internal.Mutable s (Data.Functor.Compose.Compose f g a) instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s [a] instance Data.Mutable.Internal.Mutable s a => Data.Mutable.Internal.Mutable s (Data.Vinyl.Functor.Identity a) instance Data.Mutable.Internal.Mutable s (Data.Vector.Vector a) instance Foreign.Storable.Storable a => Data.Mutable.Internal.Mutable s (Data.Vector.Storable.Vector a) instance Data.Vector.Unboxed.Base.Unbox a => Data.Mutable.Internal.Mutable s (Data.Vector.Unboxed.Base.Vector a) instance Data.Primitive.Types.Prim a => Data.Mutable.Internal.Mutable s (Data.Vector.Primitive.Vector a) instance Data.Mutable.Internal.Mutable s (Data.Primitive.Array.Array a) instance Data.Mutable.Internal.Mutable s (Data.Primitive.SmallArray.SmallArray a) instance Data.Mutable.Internal.Mutable s Data.Primitive.ByteArray.ByteArray instance Data.Primitive.Types.Prim a => Data.Mutable.Internal.Mutable s (Data.Primitive.PrimArray.PrimArray a) instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Mutable s b) => Data.Mutable.Internal.Mutable s (a, b) -- | Provides the Mutable typeclass and various helpers. See -- Data.Mutable for the main "entrypoint". Many of the datatypes -- used for Ref instances are defined in -- Data.Mutable.Instances module Data.Mutable.Class -- | An instance of Mutable s a means that a can -- be stored a mutable reference in a PrimMonad m (where -- s is the mutable state token PrimState of that monad). -- -- The associated type Ref s a links any a 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 two-fold: -- -- -- -- 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 Generic. -- -- For example, if we have a type like: -- --
--   data TwoVectors = TV
--       { tvInt    :: Vector Int
--       , tvDouble :: Vector Double
--       }
--     deriving Generic
--   
--   instance Mutable s TwoVectors where
--       type Ref s TwoVectors = GRef s TwoVectors
--   
-- -- Then now we get: -- --
--   thawRef   :: TwoVectors -> m (GRef s TwoVectors)
--   freezeRef :: GRef s TwoVectors -> m TwoVectors
--   
-- -- And GRef 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 MVectors. 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. -- -- If 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    :: HKD f (Vector Int)
--        , tvDouble :: HKD f (Vector Double)
--        }
--     deriving Generic
--   
--   instance Mutable (TwoVectors Identity) where
--       type Ref (TwoVectors Identity) = TwoVectors (RefFor s)
--   
-- -- 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 RealWorld)
--   ghci> :t is
--   MVector RealWorld Int
--   ghci> :t ds
--   MV.MVector 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 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 -- -- class Mutable s a where { -- | 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 s (Vector a) = MVector s 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, PrimState m ~ s)
    --       => Vector a
    --       -> m (Vector s a)
    --   
    --   freezeRef
    --       :: (PrimMonad m, PrimState m ~ s)
    --       => Vector s a
    --       -> m (Vector a)
    --   
    --   copyRef
    --       :: (PrimMonad m, PrimState m ~ s)
    --       => Vector s a
    --       -> Vector a
    --       -> m ()
    --   
-- -- This associated type must be unique for a, so no two types -- a can have the same Ref s a. This makes type -- inference a lot more useful: if you use freezeRef 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 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 Int. -- -- There are some built-in alternative options for user-defined ADTs with -- Generic instances: -- --
    --   -- Works for all Generic instances, preserves piecewise mutation
    --   -- for products
    --   type Ref s a = GRef s 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 s MyType
    --   
    --   -- This is equivalent to the above
    --   instance Mutable s MyType
    --       type Ref s MyType = MutVar s MyType
    --   
    --   -- any Generic instance
    --   data MyType = MyType { mtInt :: Int, mtDouble :: Double }
    --     deriving Generic
    --   
    --   instance Mutable s MyType where
    --       type Ref s MyType = GRef 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. -- -- Note that this type synonym ins injective --- this means that if you -- write a function polymorphic over Ref s a, you can -- always infer s and a (the value stored in the -- Ref). -- -- In practice, if you want to write your own instance from scratch, the -- consequence is that you must have the s type variable -- somewhere in your type (see UnitRef and VoidRef for -- examples). type family Ref s a = (v :: Type) | v -> a s; type Ref s a = MutVar s a; } -- | 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, PrimState m ~ s)
--       => Vector a
--       -> m (Vector s a)
--   
-- -- For non-composite (like Int), this is often called the "new -- var" function, like newIORef / newSTRef / -- newMutVar etc. thawRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | 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, PrimState m ~ s)
--       => Vector s a
--       -> m (Vector a)
--   
-- -- For non-composite (like Int), this is often called the "read -- var" function, like readIORef / readSTRef / -- readMutVar etc. freezeRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | 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, PrimState m ~ s)
--       => 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 non-composite (like Int), this is often called the "write -- var" function, like writeIORef / writeSTRef / -- writeMutVar etc. copyRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> a -> m () -- | Deep Copy-move a mutable reference on top of another, overwriting the -- second one. -- -- For non-composite 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. moveRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> Ref s a -> m () -- | Create a deep copy of a mutable reference, allocated to a separate -- independent reference. -- -- For non-composite 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. cloneRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a) -- | A non-copying 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. unsafeThawRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | A non-copying 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. unsafeFreezeRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | 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, PrimState m ~ s)
--       => Vector a
--       -> m (Vector s a)
--   
-- -- For non-composite (like Int), this is often called the "new -- var" function, like newIORef / newSTRef / -- newMutVar etc. thawRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | 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, PrimState m ~ s)
--       => Vector s a
--       -> m (Vector a)
--   
-- -- For non-composite (like Int), this is often called the "read -- var" function, like readIORef / readSTRef / -- readMutVar etc. freezeRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | 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, PrimState m ~ s)
--       => 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 non-composite (like Int), this is often called the "write -- var" function, like writeIORef / writeSTRef / -- writeMutVar etc. copyRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> a -> m () -- | Deep Copy-move a mutable reference on top of another, overwriting the -- second one. -- -- For non-composite 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. moveRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> Ref s a -> m () -- | Create a deep copy of a mutable reference, allocated to a separate -- independent reference. -- -- For non-composite 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. cloneRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a) -- | A non-copying 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. unsafeThawRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | A non-copying 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. unsafeFreezeRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | A default implementation of copyRef using thawRef and -- moveRef. copyRefWhole :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> a -> m () -- | A default implementation of moveRef that round-trips through -- the pure type, using freezeRef and copyRef. It freezes -- the entire source and then re-copies it into the destination. moveRefWhole :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> Ref s a -> m () -- | A default implementation of moveRef that round-trips through -- the pure type, using freezeRef and thawRef. It freezes -- the entire source and then re-copies it into the destination. cloneRefWhole :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a) -- | Apply a pure function on an immutable value onto a value stored in a -- mutable reference. modifyRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> a) -> m () -- | modifyRef, but forces the result before storing it back in the -- reference. modifyRef' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> a) -> m () -- | 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 s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> (a, b)) -> m b -- | updateRef, but forces the updated value before storing it back -- in the reference. updateRef' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> (a, b)) -> m b -- | Apply a monadic function on an immutable value onto a value stored in -- a mutable reference. Uses copyRef into the reference after the -- action is completed. modifyRefM :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> m a) -> m () -- | modifyRefM, but forces the result before storing it back in the -- reference. modifyRefM' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> m a) -> m () -- | Apply a monadic function on an immutable value onto a value stored in -- a mutable reference, returning a result value from that function. Uses -- copyRef into the reference after the action is completed. updateRefM :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> m (a, b)) -> m b -- | updateRefM, but forces the updated value before storing it back -- in the reference. updateRefM' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> m (a, b)) -> m b -- | A handy newtype wrapper that allows you to partially apply Ref. -- RefFor m a is the same as Ref s a, but -- can be partially applied. -- -- If used with HKD, you can treat this syntactically identically -- as a Ref s a. newtype RefFor s a RefFor :: Ref s a -> RefFor s a [getRefFor] :: RefFor s a -> Ref s a -- | 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 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 Generic: -- --
--   instance Mutable s MyType
--       type Ref s MyType = GRef s MyType
--   
-- -- The 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
--   
class DefaultMutable s a r | r -> a s defaultThawRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => a -> m r defaultFreezeRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => r -> m a defaultCopyRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => r -> a -> m () defaultMoveRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => r -> r -> m () defaultCloneRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => r -> m r defaultUnsafeThawRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => a -> m r defaultUnsafeFreezeRef :: (DefaultMutable s a r, PrimMonad m, PrimState m ~ s) => r -> m a -- | Newtype wrapper that can provide any type with a Mutable -- instance, giving it a "non-piecewise" instance. Can be useful for -- avoiding orphan instances yet still utilizing auto-deriving features, -- or for overwriting the Mutable instance of other instances. -- -- For example, let's say you want to auto-derive an instance for your -- data type: -- --
--   data MyType = MT Int Double OtherType
--     deriving Generic
--   
-- -- This is possible if all of MyTypes 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 auto-derived: -- --
--   instance Mutable s MyType where
--       type Ref s MyType = GRef s MyType
--   
-- -- It can also be used to override a Mutable instance. For -- example, even if the Mutable instance of SomeType is -- piecewise-mutable, the Mutable instance of VarMut -- SomeType will be not be piecewise. -- -- 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 VarMut -- String to get that Mutable instance. newtype VarMut a VarMut :: a -> VarMut a [getVarMut] :: VarMut a -> a -- | 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 Vectors Mutable -- instance (via MVector), but you don't want to write an orphan -- instance like -- --
--   instance Mutable s DoubleVec where
--       type Ref s DoubleVec = CoerceRef s DoubleVec (Vector Double)
--   
-- -- then you can instead use CoerceMut DoubleVec (Vector -- Double) as the data type. This wrapped type does use the -- inderlying Mutable insatnce for Vector. newtype CoerceMut s a CoerceMut :: s -> CoerceMut s a [getCoerceMut] :: CoerceMut s a -> s -- | 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 Mutable (TraverseMut [] -- a) is a normal list of mutable references, instead of a full-on -- mutable linked list. newtype TraverseMut f a TraverseMut :: f a -> TraverseMut f a [getTraverseMut] :: TraverseMut f a -> f a -- | 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 s MyType where
--       type Ref s MyType = GRef s MyType
--   
-- -- This basically uses three mutable references: the Int, the -- Vector Double, and the String. 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 s MyType where
--       type Ref s MyType = GRef s MyType
--   
-- -- which has that behavior. The Int and the Vector will be -- mutable within Ref s MyType, but not the -- String. newtype Immutable s a Immutable :: a -> Immutable s a [getImmutable] :: Immutable s a -> a -- | Useful type family to Ref m over every item in a -- type-level list -- --
--   ghci> :kind! MapRef IO '[Int, V.Vector Double]
--   '[ MutVar RealWorld Int, MVector RealWorld Double ]
--   
type family MapRef s as instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Data.Mutable.Class.TraverseMut f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Data.Mutable.Class.TraverseMut f) instance GHC.Base.Functor f => GHC.Base.Functor (Data.Mutable.Class.TraverseMut f) instance forall k (f :: k -> *) (a :: k). GHC.Generics.Generic (Data.Mutable.Class.TraverseMut f a) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Ord (f a) => GHC.Classes.Ord (Data.Mutable.Class.TraverseMut f a) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Eq (f a) => GHC.Classes.Eq (Data.Mutable.Class.TraverseMut f a) instance forall k (f :: k -> *) (a :: k). GHC.Show.Show (f a) => GHC.Show.Show (Data.Mutable.Class.TraverseMut f a) instance forall k (s :: k) a. Data.Vinyl.XRec.IsoHKD (Data.Mutable.Class.Immutable s) a instance Data.Mutable.Internal.Mutable s (Data.Mutable.Class.Immutable s a) instance forall k s (a :: k). Data.Vinyl.XRec.IsoHKD (Data.Mutable.Class.CoerceMut s) a instance (Data.Mutable.Internal.Mutable s a, GHC.Types.Coercible s a) => Data.Mutable.Internal.Mutable s (Data.Mutable.Class.CoerceMut s a) instance forall k (f :: k -> *) (a :: k). Data.Vinyl.XRec.IsoHKD (Data.Mutable.Class.TraverseMut f) a instance (Data.Traversable.Traversable f, Data.Mutable.Internal.Mutable s a) => Data.Mutable.Internal.Mutable s (Data.Mutable.Class.TraverseMut f a) instance Data.Vinyl.XRec.IsoHKD Data.Mutable.Class.VarMut a instance Data.Mutable.Internal.Mutable s (Data.Mutable.Class.VarMut a) -- | Tools for working with potential branches of piecewise-mutable values. -- -- If Data.Mutable.Parts is for product types, then -- Data.Mutable.Branches is for sum types. -- -- See https://mutable.jle.im/06-mutable-branches.html for an -- introduction to this module. module Data.Mutable.Branches -- | A MutBranch s b a represents the information that -- b could potentially be an a. Similar in spirit to a -- Prism' b a. -- -- MutBranch 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 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 s (Either a b) a
--   constrMB #_Right  :: MutBranch s (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 s a => Mutable s (List a) where
--       type Ref s (List a) = GRef s (List a)
--   
-- -- GRef s (List a) is now a mutable linked list! Once we -- make the MutBranch 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
--   
data MutBranch s b a MutBranch :: (forall m. (PrimMonad m, PrimState m ~ s) => Ref s b -> m (Maybe (Ref s a))) -> (forall m. (PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s b)) -> MutBranch s b a -- | With a MutBranch, 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"
--   
[projectBranch] :: MutBranch s b a -> forall m. (PrimMonad m, PrimState m ~ s) => Ref s b -> m (Maybe (Ref s a)) -- | 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 Either ref will cause it to -- loose the original reference: -- --
--   ghci> copyRef s (Right True)
--   ghci> copyRef s (Left 999)
--   ghci> freezeRef r
--   0
--   
[embedBranch] :: MutBranch s b a -> forall m. (PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s b) -- | With a MutBranch, thaw an a into a mutable s -- on that branch. -- --
--   ghci> r <- thawBranch (constrMB #_Left) 10
--   ghci> freezeRef r
--   Left 10
--   
thawBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> a -> m (Ref s b) -- | 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
--   
freezeBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m (Maybe a) -- | Check if an s is currently a certain branch a. hasBranch :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m Bool -- | Check if an s is not currently a certain branch -- a. hasn'tBranch :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m Bool -- | 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
--   
moveBranch :: (Mutable s b, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> Ref s a -> 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
--   
copyBranch :: (Mutable s b, Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> a -> m () -- | 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"
--   
cloneBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m (Maybe (Ref s a)) -- | A non-copying 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. unsafeThawBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> a -> m (Ref s b) -- | A non-copying 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. unsafeFreezeBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m (Maybe a) -- | 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
--   
withBranch :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (Ref s a -> m r) -> m (Maybe r) -- | withBranch, but discarding the returned value. withBranch_ :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (Ref s a -> m r) -> 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
--   
modifyBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> a) -> m () -- | modifyBranch, but forces the result before storing it back in -- the reference. modifyBranch' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> a) -> m () -- | 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
--   
updateBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> (a, r)) -> m (Maybe r) -- | updateBranch, but forces the result before storing it back in -- the reference. updateBranch' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> (a, r)) -> m (Maybe r) -- | modifyBranch but for a monadic function. Uses copyRef -- into the reference after the action is completed. modifyBranchM :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> m a) -> m () -- | modifyBranchM, but forces the result before storing it back in -- the reference. modifyBranchM' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> m a) -> m () -- | updateBranch but for a monadic function. Uses copyRef -- into the reference after the action is completed. updateBranchM :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> m (a, r)) -> m (Maybe r) -- | updateBranchM, but forces the result before storing it back in -- the reference. updateBranchM' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> m (a, r)) -> m (Maybe r) -- | Compose two MutBranchs, to drill down on what is being focused. compMB :: MutBranch s a b -> MutBranch s b c -> MutBranch s a c -- | An identity MutBranch, treating the item itself as a whole -- branch. cloneBranch will always "match". idMB :: MutBranch s a a -- | 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 s a) => MutBranch s [a] (a, [a])
--   consMB = constrMB (CLabel @":")
--   
constrMB :: forall ctor s b a. (Ref s b ~ GRef s b, GMutBranchConstructor ctor s (Rep b) a) => CLabel ctor -> MutBranch s b a -- | 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. data CLabel (ctor :: Symbol) CLabel :: CLabel (ctor :: Symbol) -- | Typeclass powering constrMB using GHC Generics. -- -- Heavily inspired by Data.Generics.Sum.Constructors. class (GMutable s f, Mutable s a) => GMutBranchConstructor (ctor :: Symbol) s f a | ctor f -> a -- | Useful type family to Ref m over every item in a -- type-level list -- --
--   ghci> :kind! MapRef IO '[Int, V.Vector Double]
--   '[ MutVar RealWorld Int, MVector RealWorld Double ]
--   
type family MapRef s as -- | MutBranch focusing on the nil case of a list nilMB :: Mutable s a => MutBranch s [a] () -- | MutBranch focusing on the cons case of a list consMB :: Mutable s a => MutBranch s [a] (a, [a]) -- | MutBranch focusing on the Nothing case of a Maybe nothingMB :: Mutable s a => MutBranch s (Maybe a) () -- | MutBranch focusing on the Just case of a Maybe justMB :: Mutable s a => MutBranch s (Maybe a) a -- | MutBranch focusing on the Left case of an Either leftMB :: (Mutable s a, Mutable s b) => MutBranch s (Either a b) a -- | MutBranch focusing on the Right case of an Either rightMB :: (Mutable s a, Mutable s b) => MutBranch s (Either a b) b instance (Data.Mutable.Internal.Mutable s a, Data.Mutable.Branches.GMutBranchSum ctor (Data.Generics.Internal.Families.Has.HasCtorP ctor l) s l r a) => Data.Mutable.Branches.GMutBranchConstructor ctor s (l GHC.Generics.:+: r) a instance (Data.Mutable.Internal.GMutable s r, Data.Mutable.Branches.GMutBranchConstructor ctor s l a, Data.Generics.Product.Internal.HList.GIsList (Data.Mutable.Internal.GRef_ s l) (Data.Mutable.Internal.GRef_ s l) (Data.Mutable.Internal.MapRef s as) (Data.Mutable.Internal.MapRef s as), Data.Generics.Product.Internal.HList.GIsList l l as as, Data.Generics.Product.Internal.HList.ListTuple a a as as, Data.Mutable.Internal.ListRefTuple s b as, Data.Mutable.Internal.Ref s a GHC.Types.~ b) => Data.Mutable.Branches.GMutBranchSum ctor 'GHC.Types.True s l r a instance (Data.Mutable.Internal.GMutable s l, Data.Mutable.Branches.GMutBranchConstructor ctor s r a, Data.Mutable.Internal.Ref s a GHC.Types.~ b) => Data.Mutable.Branches.GMutBranchSum ctor 'GHC.Types.False s l r a instance (Data.Mutable.Internal.GMutable s f, Data.Mutable.Internal.Mutable s a, Data.Generics.Product.Internal.HList.GIsList (Data.Mutable.Internal.GRef_ s f) (Data.Mutable.Internal.GRef_ s f) (Data.Mutable.Internal.MapRef s as) (Data.Mutable.Internal.MapRef s as), Data.Generics.Product.Internal.HList.GIsList f f as as, Data.Generics.Product.Internal.HList.ListTuple a a as as, Data.Mutable.Internal.ListRefTuple s b as, Data.Mutable.Internal.Ref s a GHC.Types.~ b) => Data.Mutable.Branches.GMutBranchConstructor ctor s (GHC.Generics.M1 GHC.Generics.C ('GHC.Generics.MetaCons ctor fixity fields) f) a instance Data.Mutable.Branches.GMutBranchConstructor ctor m f a => Data.Mutable.Branches.GMutBranchConstructor ctor m (GHC.Generics.M1 GHC.Generics.D meta f) a instance (ctor_ GHC.Types.~ GHC.TypeLits.AppendSymbol "_" ctor) => GHC.OverloadedLabels.IsLabel ctor_ (Data.Mutable.Branches.CLabel ctor) -- | Tools for working with individual components of piecewise-mutable -- values. -- -- If Data.Mutable.Branches is for sum types, then -- Data.Mutable.Parts is for sum types. -- -- See https://mutable.jle.im/05-mutable-parts.html for an -- introduction to this module. module Data.Mutable.Parts -- | A MutPart 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 MutBranch is for sum types, then MutPart 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 -> MVector s a -> a -> m -- () from Data.Vector.Mutable --- write 3 :: -- MVector s a -> a -> m (), for instance, lets you -- modify a specific part of the vector without touching the rest. -- -- You would use a MutPart using freezePart, -- copyPart, modifyPart, 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: -- --
--   mutFst :: MutPart s (a, b) a
--   mutSnd :: MutPart s (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 automatically-defined mutable -- reference, then the easiest way to create these for your mutable types -- are with fieldMut and posMut. -- -- If you are using the "Higher-kinded 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. newtype MutPart s b a MutPart :: (Ref s b -> Ref s a) -> MutPart s b a [getMutPart] :: MutPart s b a -> Ref s b -> Ref s a -- | Using a MutPart, perform a function on a Ref s -- s as if you had a Ref s a. withPart :: MutPart s b a -> Ref s b -> (Ref s a -> m r) -> m r -- | With a MutPart, read out a specific part of a Ref. freezePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> m a -- | With a MutPart, overwrite into a specific part of a Ref. copyPart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> a -> 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 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
--   
movePartInto :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> Ref s a -> 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 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
--   
movePartOver :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s a -> Ref s b -> m () -- | 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 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
--   
movePartWithin :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> Ref s b -> m () -- | Clone out a subvalue of a larger Ref. clonePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> m (Ref s a) -- | A non-copying 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. unsafeFreezePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> m a -- | With a MutPart, modify a specific part of a Ref with a -- pure function. modifyPart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> a) -> m () -- | modifyPart, but forces the result before storing it back in the -- reference. modifyPart' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> a) -> m () -- | updateRef, under a MutPart to only modify a specific -- part of a Ref. updatePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> (a, r)) -> m r -- | updatePart, but forces the result before storing it back in the -- reference. updatePart' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> (a, r)) -> m r -- | With a MutPart, modify a specific part of a Ref with a -- monadic function. Uses copyRef into the reference after the -- action is completed. modifyPartM :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> m a) -> m () -- | modifyPartM, but forces the result before storing it back in -- the reference. modifyPartM' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> m a) -> m () -- | updateRefM, under a MutPart to only modify a specific -- part of a Ref. copyRef into the reference after the -- action is completed. updatePartM :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> m (a, r)) -> m r -- | updatePartM, but forces the result before storing it back in -- the reference. updatePartM' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> m (a, r)) -> m r -- | Compose two MutParts one after the other. -- -- Note this is also available (albeit flipped in arguments) through the -- Category instance. compMP :: MutPart s a b -> MutPart s b c -> MutPart s a c infixr 9 `compMP` -- | The identity MutPart: simply focus into the same type itself. -- -- Note this is also available through the Category instance. idMP :: MutPart s a a -- | MutPart into the first field of a tuple reference. mutFst :: MutPart s (a, b) a -- | MutPart into the second field of a tuple reference. mutSnd :: MutPart s (a, b) b -- | 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. class (Mutable s b, Mutable s a) => FieldMut (fld :: Symbol) s b a | fld b -> a -- | 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 s MyType where
--       type Ref s MyType = GRef s 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 compile-time, fieldMut and -- posMut have more or less identical performance characteristics. fieldMut :: FieldMut fld s b a => Label fld -> MutPart s b a -- | A helpful wrapper over withPart (fieldMut -- #blah). Create a fieldMut and directly use it. withField :: FieldMut fld s b a => Label fld -> Ref s b -> (Ref s a -> m r) -> m r -- | A helpful wrapper around getMutPart (fieldMut -- #blah). Directly use a fieldMut to access a mutable field. mutField :: forall fld s b a. FieldMut fld s b a => Label fld -> Ref s b -> Ref s a -- | Proxy for label type data Label (a :: Symbol) Label :: Label (a :: Symbol) -- | 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. class (Mutable s b, Mutable s a) => PosMut (i :: Nat) s b a | i b -> a -- | 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 s MyType where
--       type Ref s MyType = GRef s 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 compile-time, -- posMut and fieldMut have more or less identical -- performance characteristics. posMut :: PosMut i s b a => MutPart s b a -- | A helpful wrapper over withPart (posMut @n). -- Create a posMut and directly use it. withPos :: forall i s m b a r. PosMut i s b a => Ref s b -> (Ref s a -> m r) -> m r -- | A helpful wrapper around getMutPart (posMut -- @n). Directly use a posMut to access a mutable field. mutPos :: forall i s b a. PosMut i s b a => Ref s b -> Ref s a -- | 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. class (Mutable s b, Mutable s a) => TupleMut s b a | b -> a -- | 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 s MyType where
--       type Ref s MyType = GRef s 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. -- -- Performance-wise, this appears to be faster than fieldMut and -- posMut when using a single reference, but slower if using all -- references. tupleMut :: TupleMut s b a => MutPart s b a -- | A helpful wrapper over withPart tupleMut. -- Directly operate on the items in the data type, getting the references -- as a tuple. See tupleMut 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 = GRef s 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
--   
withTuple :: TupleMut s b a => Ref s b -> (Ref s a -> m r) -> m r -- | If you are using the "higher-kinded data" pattern, a la -- https://reasonablypolymorphic.com/blog/higher-kinded-data/, 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 (MyTypeF Identity) where
--       type Ref (MyTypeF Identity) = MyTypeF (RefFor m)
--   
--   mx :: MutPart s (MyTypeF Identity) (Vector Int)
--   my :: MutPart s (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
--   
-- -- Performance-wise, 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 case-by-case -- basis. hkdMutParts :: forall z s. (Generic (z (RefFor s)), Generic (z (MutPart s (z Identity))), HKDMutParts s z (Rep (z (RefFor s))) (Rep (z (MutPart s (z Identity))))) => z (MutPart s (z Identity)) -- | Typeclass used to implement hkdMutParts. See documentation of -- hkdMutParts for more information. class (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s)) => HKDMutParts s z i o -- | 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
--   
mutRec :: forall a as f rec s. (Ref s (rec f as) ~ rec (RecRef s f) as, RecElem rec a a as as (RIndex a as), RecElemFCtx rec (RecRef s f)) => MutPart s (rec f as) (f a) -- | A MutPart to get into a CoerceRef. coerceRef :: Ref s b ~ CoerceRef s b a => MutPart s b a -- | Handy wrapper over getMutPart coerceRef. withCoerceRef :: CoerceRef s b a -> (Ref s a -> m r) -> m r -- | Useful type family to Ref m over every item in a -- type-level list -- --
--   ghci> :kind! MapRef IO '[Int, V.Vector Double]
--   '[ MutVar RealWorld Int, MVector RealWorld Double ]
--   
type family MapRef s as instance (Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Ref s b GHC.Types.~ Data.Mutable.Internal.GRef s b, gref GHC.Types.~ Data.Mutable.Parts.Fst (Data.Mutable.Parts.Traverse (Data.Mutable.Internal.GRef_ s (Data.Generics.Product.Internal.Positions.CRep b)) 1), GHC.Types.Coercible (Data.Mutable.Internal.GRef_ s (GHC.Generics.Rep b) ()) (gref ()), Data.Generics.Product.Internal.GLens.GLens' (Data.Mutable.Parts.HasTotalPositionPSym i) gref (Data.Mutable.Internal.Ref s a), Data.Generics.Product.Positions.HasPosition' i b a) => Data.Mutable.Parts.PosMut i s b a instance (Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Ref s b GHC.Types.~ Data.Mutable.Internal.GRef s b, Data.Generics.Product.Internal.HList.GIsList (Data.Mutable.Internal.GRef_ s (GHC.Generics.Rep b)) (Data.Mutable.Internal.GRef_ s (GHC.Generics.Rep b)) (Data.Mutable.Internal.MapRef s as) (Data.Mutable.Internal.MapRef s as), Data.Generics.Product.Internal.HList.GIsList (GHC.Generics.Rep b) (GHC.Generics.Rep b) as as, Data.Generics.Product.Internal.HList.ListTuple a a as as, Data.Generics.Product.Internal.HList.ListTuple c c (Data.Mutable.Internal.MapRef s as) (Data.Mutable.Internal.MapRef s as), Data.Mutable.Internal.Ref s a GHC.Types.~ c) => Data.Mutable.Parts.TupleMut s b a instance (Data.Mutable.Internal.Mutable s b, Data.Mutable.Internal.Mutable s a, Data.Mutable.Internal.Ref s b GHC.Types.~ Data.Mutable.Internal.GRef s b, Data.Generics.Product.Internal.GLens.GLens' (Data.Mutable.Parts.HasTotalFieldPSym fld) (Data.Mutable.Internal.GRef_ s (GHC.Generics.Rep b)) (Data.Mutable.Internal.Ref s a), Data.Generics.Product.Fields.HasField' fld b a) => Data.Mutable.Parts.FieldMut fld s b a instance (Data.Mutable.Internal.Mutable s (z Data.Vinyl.Functor.Identity), Data.Mutable.Internal.Ref s (z Data.Vinyl.Functor.Identity) GHC.Types.~ z (Data.Mutable.Internal.RefFor s)) => Data.Mutable.Parts.HKDMutParts s z (GHC.Generics.K1 i (Data.Mutable.Internal.RefFor s c)) (GHC.Generics.K1 i (Data.Mutable.Parts.MutPart s (z Data.Vinyl.Functor.Identity) c)) instance (Data.Mutable.Internal.Mutable s (z Data.Vinyl.Functor.Identity), Data.Mutable.Internal.Ref s (z Data.Vinyl.Functor.Identity) GHC.Types.~ z (Data.Mutable.Internal.RefFor s)) => Data.Mutable.Parts.HKDMutParts s z GHC.Generics.U1 GHC.Generics.U1 instance (Data.Mutable.Internal.Mutable s (z Data.Vinyl.Functor.Identity), Data.Mutable.Internal.Ref s (z Data.Vinyl.Functor.Identity) GHC.Types.~ z (Data.Mutable.Internal.RefFor s), (TypeError ...)) => Data.Mutable.Parts.HKDMutParts s z GHC.Generics.V1 GHC.Generics.V1 instance forall k s (z :: (* -> *) -> *) (i :: k -> *) (o :: k -> *) a (b :: GHC.Generics.Meta). Data.Mutable.Parts.HKDMutParts s z i o => Data.Mutable.Parts.HKDMutParts s z (GHC.Generics.M1 a b i) (GHC.Generics.M1 a b o) instance forall k s (z :: (* -> *) -> *) (i :: k -> *) (o :: k -> *) (i' :: k -> *) (o' :: k -> *). (Data.Mutable.Parts.HKDMutParts s z i o, Data.Mutable.Parts.HKDMutParts s z i' o') => Data.Mutable.Parts.HKDMutParts s z (i GHC.Generics.:*: i') (o GHC.Generics.:*: o') instance forall k s (z :: (* -> *) -> *) (i :: k -> *) (i' :: k -> *) (o :: k -> *). (Data.Mutable.Internal.Mutable s (z Data.Vinyl.Functor.Identity), Data.Mutable.Internal.Ref s (z Data.Vinyl.Functor.Identity) GHC.Types.~ z (Data.Mutable.Internal.RefFor s), (TypeError ...)) => Data.Mutable.Parts.HKDMutParts s z (i GHC.Generics.:+: i') o instance Control.Category.Category (Data.Mutable.Parts.MutPart s) instance Data.Vinyl.XRec.IsoHKD (Data.Mutable.Parts.MutPart s b) a -- | Main entrypoint of the package. Abstract over different types for -- piecewise-mutable references of values. -- -- See https://mutable.jle.im/ for a comprehensive introduction. module Data.Mutable -- | An instance of Mutable s a means that a can -- be stored a mutable reference in a PrimMonad m (where -- s is the mutable state token PrimState of that monad). -- -- The associated type Ref s a links any a 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 two-fold: -- -- -- -- 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 Generic. -- -- For example, if we have a type like: -- --
--   data TwoVectors = TV
--       { tvInt    :: Vector Int
--       , tvDouble :: Vector Double
--       }
--     deriving Generic
--   
--   instance Mutable s TwoVectors where
--       type Ref s TwoVectors = GRef s TwoVectors
--   
-- -- Then now we get: -- --
--   thawRef   :: TwoVectors -> m (GRef s TwoVectors)
--   freezeRef :: GRef s TwoVectors -> m TwoVectors
--   
-- -- And GRef 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 MVectors. 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. -- -- If 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    :: HKD f (Vector Int)
--        , tvDouble :: HKD f (Vector Double)
--        }
--     deriving Generic
--   
--   instance Mutable (TwoVectors Identity) where
--       type Ref (TwoVectors Identity) = TwoVectors (RefFor s)
--   
-- -- 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 RealWorld)
--   ghci> :t is
--   MVector RealWorld Int
--   ghci> :t ds
--   MV.MVector 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 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 -- -- class Mutable s a where { -- | 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 s (Vector a) = MVector s 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, PrimState m ~ s)
    --       => Vector a
    --       -> m (Vector s a)
    --   
    --   freezeRef
    --       :: (PrimMonad m, PrimState m ~ s)
    --       => Vector s a
    --       -> m (Vector a)
    --   
    --   copyRef
    --       :: (PrimMonad m, PrimState m ~ s)
    --       => Vector s a
    --       -> Vector a
    --       -> m ()
    --   
-- -- This associated type must be unique for a, so no two types -- a can have the same Ref s a. This makes type -- inference a lot more useful: if you use freezeRef 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 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 Int. -- -- There are some built-in alternative options for user-defined ADTs with -- Generic instances: -- --
    --   -- Works for all Generic instances, preserves piecewise mutation
    --   -- for products
    --   type Ref s a = GRef s 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 s MyType
    --   
    --   -- This is equivalent to the above
    --   instance Mutable s MyType
    --       type Ref s MyType = MutVar s MyType
    --   
    --   -- any Generic instance
    --   data MyType = MyType { mtInt :: Int, mtDouble :: Double }
    --     deriving Generic
    --   
    --   instance Mutable s MyType where
    --       type Ref s MyType = GRef 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. -- -- Note that this type synonym ins injective --- this means that if you -- write a function polymorphic over Ref s a, you can -- always infer s and a (the value stored in the -- Ref). -- -- In practice, if you want to write your own instance from scratch, the -- consequence is that you must have the s type variable -- somewhere in your type (see UnitRef and VoidRef for -- examples). type family Ref s a = (v :: Type) | v -> a s; type Ref s a = MutVar s a; } -- | 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, PrimState m ~ s)
--       => Vector a
--       -> m (Vector s a)
--   
-- -- For non-composite (like Int), this is often called the "new -- var" function, like newIORef / newSTRef / -- newMutVar etc. thawRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | 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, PrimState m ~ s)
--       => Vector s a
--       -> m (Vector a)
--   
-- -- For non-composite (like Int), this is often called the "read -- var" function, like readIORef / readSTRef / -- readMutVar etc. freezeRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | 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, PrimState m ~ s)
--       => 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 non-composite (like Int), this is often called the "write -- var" function, like writeIORef / writeSTRef / -- writeMutVar etc. copyRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> a -> m () -- | Deep Copy-move a mutable reference on top of another, overwriting the -- second one. -- -- For non-composite 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. moveRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> Ref s a -> m () -- | Create a deep copy of a mutable reference, allocated to a separate -- independent reference. -- -- For non-composite 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. cloneRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a) -- | A non-copying 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. unsafeThawRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | A non-copying 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. unsafeFreezeRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | 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, PrimState m ~ s)
--       => Vector a
--       -> m (Vector s a)
--   
-- -- For non-composite (like Int), this is often called the "new -- var" function, like newIORef / newSTRef / -- newMutVar etc. thawRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | 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, PrimState m ~ s)
--       => Vector s a
--       -> m (Vector a)
--   
-- -- For non-composite (like Int), this is often called the "read -- var" function, like readIORef / readSTRef / -- readMutVar etc. freezeRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | 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, PrimState m ~ s)
--       => 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 non-composite (like Int), this is often called the "write -- var" function, like writeIORef / writeSTRef / -- writeMutVar etc. copyRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> a -> m () -- | Deep Copy-move a mutable reference on top of another, overwriting the -- second one. -- -- For non-composite 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. moveRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> Ref s a -> m () -- | Create a deep copy of a mutable reference, allocated to a separate -- independent reference. -- -- For non-composite 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. cloneRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a) -- | A non-copying 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. unsafeThawRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => a -> m (Ref s a) -- | A non-copying 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. unsafeFreezeRef :: (Mutable s a, DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m a -- | Apply a pure function on an immutable value onto a value stored in a -- mutable reference. modifyRef :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> a) -> m () -- | modifyRef, but forces the result before storing it back in the -- reference. modifyRef' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> a) -> m () -- | 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 s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> (a, b)) -> m b -- | updateRef, but forces the updated value before storing it back -- in the reference. updateRef' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => Ref s a -> (a -> (a, b)) -> m b -- | A handy newtype wrapper that allows you to partially apply Ref. -- RefFor m a is the same as Ref s a, but -- can be partially applied. -- -- If used with HKD, you can treat this syntactically identically -- as a Ref s a. newtype RefFor s a RefFor :: Ref s a -> RefFor s a [getRefFor] :: RefFor s a -> Ref s a -- | 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 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 Generic: -- --
--   instance Mutable s MyType
--       type Ref s MyType = GRef s MyType
--   
-- -- The 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
--   
class DefaultMutable s a r | r -> a s -- | Automatically generate a piecewise mutable reference for any -- Generic instance. -- --
--   -- | any Generic instance
--   data MyType = MyType { mtInt :: Int, mtDouble :: Double }
--     deriving (Generic, Show)
--   
--   instance Mutable s MyType where
--       type Ref s MyType = GRef s 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 unGRef @MyType 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. data GRef s a -- | A MutVar behaves like a single-element mutable array associated -- with a primitive state token. data MutVar s a -- | 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)
--   
--   instance Mutable s MyVec where
--       type Ref s MyVec = CoerceRef s s (Vector Double)
--   
-- -- The Ref s MyVec uses the a MVector Double -- under the hood. -- -- It's essentially a special case of GRef for newtypes. newtype CoerceRef s b a CoerceRef :: Ref s a -> CoerceRef s b a [getCoerceRef] :: CoerceRef s b a -> Ref s a -- | 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 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: -- -- -- --
--   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]
--   
newtype TraverseRef s f a TraverseRef :: f (Ref s a) -> TraverseRef s f a [getTraverseRef] :: TraverseRef s f a -> f (Ref s a) -- | A Ref for instances of GMutable, which are the -- GHC.Generics combinators. newtype GMutableRef s f a GMutableRef :: GRef_ s f a -> GMutableRef s f a [getGMutableRef] :: GMutableRef s f a -> GRef_ s f a -- | Ref for components in a vinyl Rec. newtype RecRef s f a RecRef :: Ref s (f a) -> RecRef s f a [getRecRef] :: RecRef s f a -> Ref s (f a) -- | The mutable reference of the HList type from generic-lens. data HListRef :: Type -> [Type] -> Type [NilRef] :: HListRef s '[] [:!>] :: Ref s a -> HListRef s as -> HListRef s (a : as) infixr 5 :!> -- | The Ref for () (unit). This breaks the pattern for -- tuple instances (type Ref s (a, b) = (Ref s a, -- Ref s b)), but is necessary for type inference (see -- documentation for Ref). data UnitRef s UnitRef :: UnitRef s -- | The Ref for Void. data VoidRef s -- | Newtype wrapper that can provide any type with a Mutable -- instance, giving it a "non-piecewise" instance. Can be useful for -- avoiding orphan instances yet still utilizing auto-deriving features, -- or for overwriting the Mutable instance of other instances. -- -- For example, let's say you want to auto-derive an instance for your -- data type: -- --
--   data MyType = MT Int Double OtherType
--     deriving Generic
--   
-- -- This is possible if all of MyTypes 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 auto-derived: -- --
--   instance Mutable s MyType where
--       type Ref s MyType = GRef s MyType
--   
-- -- It can also be used to override a Mutable instance. For -- example, even if the Mutable instance of SomeType is -- piecewise-mutable, the Mutable instance of VarMut -- SomeType will be not be piecewise. -- -- 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 VarMut -- String to get that Mutable instance. newtype VarMut a VarMut :: a -> VarMut a [getVarMut] :: VarMut a -> a -- | 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 Vectors Mutable -- instance (via MVector), but you don't want to write an orphan -- instance like -- --
--   instance Mutable s DoubleVec where
--       type Ref s DoubleVec = CoerceRef s DoubleVec (Vector Double)
--   
-- -- then you can instead use CoerceMut DoubleVec (Vector -- Double) as the data type. This wrapped type does use the -- inderlying Mutable insatnce for Vector. newtype CoerceMut s a CoerceMut :: s -> CoerceMut s a [getCoerceMut] :: CoerceMut s a -> s -- | 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 Mutable (TraverseMut [] -- a) is a normal list of mutable references, instead of a full-on -- mutable linked list. newtype TraverseMut f a TraverseMut :: f a -> TraverseMut f a [getTraverseMut] :: TraverseMut f a -> f a -- | 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 s MyType where
--       type Ref s MyType = GRef s MyType
--   
-- -- This basically uses three mutable references: the Int, the -- Vector Double, and the String. 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 s MyType where
--       type Ref s MyType = GRef s MyType
--   
-- -- which has that behavior. The Int and the Vector will be -- mutable within Ref s MyType, but not the -- String. newtype Immutable s a Immutable :: a -> Immutable s a [getImmutable] :: Immutable s a -> a -- | A MutPart 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 MutBranch is for sum types, then MutPart 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 -> MVector s a -> a -> m -- () from Data.Vector.Mutable --- write 3 :: -- MVector s a -> a -> m (), for instance, lets you -- modify a specific part of the vector without touching the rest. -- -- You would use a MutPart using freezePart, -- copyPart, modifyPart, 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: -- --
--   mutFst :: MutPart s (a, b) a
--   mutSnd :: MutPart s (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 automatically-defined mutable -- reference, then the easiest way to create these for your mutable types -- are with fieldMut and posMut. -- -- If you are using the "Higher-kinded 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. newtype MutPart s b a MutPart :: (Ref s b -> Ref s a) -> MutPart s b a [getMutPart] :: MutPart s b a -> Ref s b -> Ref s a -- | Using a MutPart, perform a function on a Ref s -- s as if you had a Ref s a. withPart :: MutPart s b a -> Ref s b -> (Ref s a -> m r) -> m r -- | With a MutPart, read out a specific part of a Ref. freezePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> m a -- | With a MutPart, overwrite into a specific part of a Ref. copyPart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> a -> 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 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
--   
movePartInto :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> Ref s a -> 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 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
--   
movePartOver :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s a -> Ref s b -> m () -- | 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 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
--   
movePartWithin :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> Ref s b -> m () -- | Clone out a subvalue of a larger Ref. clonePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> m (Ref s a) -- | A non-copying 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. unsafeFreezePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> m a -- | With a MutPart, modify a specific part of a Ref with a -- pure function. modifyPart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> a) -> m () -- | modifyPart, but forces the result before storing it back in the -- reference. modifyPart' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> a) -> m () -- | updateRef, under a MutPart to only modify a specific -- part of a Ref. updatePart :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> (a, r)) -> m r -- | updatePart, but forces the result before storing it back in the -- reference. updatePart' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutPart s b a -> Ref s b -> (a -> (a, r)) -> m r -- | 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. class (Mutable s b, Mutable s a) => FieldMut (fld :: Symbol) s b a | fld b -> a -- | 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 s MyType where
--       type Ref s MyType = GRef s 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 compile-time, fieldMut and -- posMut have more or less identical performance characteristics. fieldMut :: FieldMut fld s b a => Label fld -> MutPart s b a -- | A helpful wrapper over withPart (fieldMut -- #blah). Create a fieldMut and directly use it. withField :: FieldMut fld s b a => Label fld -> Ref s b -> (Ref s a -> m r) -> m r -- | A helpful wrapper around getMutPart (fieldMut -- #blah). Directly use a fieldMut to access a mutable field. mutField :: forall fld s b a. FieldMut fld s b a => Label fld -> Ref s b -> Ref s a -- | Proxy for label type data Label (a :: Symbol) Label :: Label (a :: Symbol) -- | 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. class (Mutable s b, Mutable s a) => PosMut (i :: Nat) s b a | i b -> a -- | 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 s MyType where
--       type Ref s MyType = GRef s 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 compile-time, -- posMut and fieldMut have more or less identical -- performance characteristics. posMut :: PosMut i s b a => MutPart s b a -- | A helpful wrapper over withPart (posMut @n). -- Create a posMut and directly use it. withPos :: forall i s m b a r. PosMut i s b a => Ref s b -> (Ref s a -> m r) -> m r -- | A helpful wrapper around getMutPart (posMut -- @n). Directly use a posMut to access a mutable field. mutPos :: forall i s b a. PosMut i s b a => Ref s b -> Ref s a -- | 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. class (Mutable s b, Mutable s a) => TupleMut s b a | b -> a -- | 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 s MyType where
--       type Ref s MyType = GRef s 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. -- -- Performance-wise, this appears to be faster than fieldMut and -- posMut when using a single reference, but slower if using all -- references. tupleMut :: TupleMut s b a => MutPart s b a -- | A helpful wrapper over withPart tupleMut. -- Directly operate on the items in the data type, getting the references -- as a tuple. See tupleMut 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 = GRef s 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
--   
withTuple :: TupleMut s b a => Ref s b -> (Ref s a -> m r) -> m r -- | If you are using the "higher-kinded data" pattern, a la -- https://reasonablypolymorphic.com/blog/higher-kinded-data/, 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 (MyTypeF Identity) where
--       type Ref (MyTypeF Identity) = MyTypeF (RefFor m)
--   
--   mx :: MutPart s (MyTypeF Identity) (Vector Int)
--   my :: MutPart s (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
--   
-- -- Performance-wise, 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 case-by-case -- basis. hkdMutParts :: forall z s. (Generic (z (RefFor s)), Generic (z (MutPart s (z Identity))), HKDMutParts s z (Rep (z (RefFor s))) (Rep (z (MutPart s (z Identity))))) => z (MutPart s (z Identity)) -- | Typeclass used to implement hkdMutParts. See documentation of -- hkdMutParts for more information. class (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s)) => HKDMutParts s z i o -- | MutPart into the first field of a tuple reference. mutFst :: MutPart s (a, b) a -- | MutPart into the second field of a tuple reference. mutSnd :: MutPart s (a, b) b -- | 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
--   
mutRec :: forall a as f rec s. (Ref s (rec f as) ~ rec (RecRef s f) as, RecElem rec a a as as (RIndex a as), RecElemFCtx rec (RecRef s f)) => MutPart s (rec f as) (f a) -- | A MutPart to get into a CoerceRef. coerceRef :: Ref s b ~ CoerceRef s b a => MutPart s b a -- | Handy wrapper over getMutPart coerceRef. withCoerceRef :: CoerceRef s b a -> (Ref s a -> m r) -> m r -- | A MutBranch s b a represents the information that -- b could potentially be an a. Similar in spirit to a -- Prism' b a. -- -- MutBranch 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 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 s (Either a b) a
--   constrMB #_Right  :: MutBranch s (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 s a => Mutable s (List a) where
--       type Ref s (List a) = GRef s (List a)
--   
-- -- GRef s (List a) is now a mutable linked list! Once we -- make the MutBranch 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
--   
data MutBranch s b a MutBranch :: (forall m. (PrimMonad m, PrimState m ~ s) => Ref s b -> m (Maybe (Ref s a))) -> (forall m. (PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s b)) -> MutBranch s b a -- | With a MutBranch, 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"
--   
[projectBranch] :: MutBranch s b a -> forall m. (PrimMonad m, PrimState m ~ s) => Ref s b -> m (Maybe (Ref s a)) -- | 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 Either ref will cause it to -- loose the original reference: -- --
--   ghci> copyRef s (Right True)
--   ghci> copyRef s (Left 999)
--   ghci> freezeRef r
--   0
--   
[embedBranch] :: MutBranch s b a -> forall m. (PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s b) -- | With a MutBranch, thaw an a into a mutable s -- on that branch. -- --
--   ghci> r <- thawBranch (constrMB #_Left) 10
--   ghci> freezeRef r
--   Left 10
--   
thawBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> a -> m (Ref s b) -- | 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
--   
freezeBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m (Maybe a) -- | 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
--   
moveBranch :: (Mutable s b, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> Ref s a -> 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
--   
copyBranch :: (Mutable s b, Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> a -> m () -- | 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"
--   
cloneBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m (Maybe (Ref s a)) -- | Check if an s is currently a certain branch a. hasBranch :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m Bool -- | Check if an s is not currently a certain branch -- a. hasn'tBranch :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m Bool -- | A non-copying 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. unsafeThawBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> a -> m (Ref s b) -- | A non-copying 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. unsafeFreezeBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> m (Maybe a) -- | 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
--   
withBranch :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (Ref s a -> m r) -> m (Maybe r) -- | withBranch, but discarding the returned value. withBranch_ :: (PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (Ref s a -> m r) -> 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
--   
modifyBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> a) -> m () -- | modifyBranch, but forces the result before storing it back in -- the reference. modifyBranch' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> a) -> m () -- | 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
--   
updateBranch :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> (a, r)) -> m (Maybe r) -- | updateBranch, but forces the result before storing it back in -- the reference. updateBranch' :: (Mutable s a, PrimMonad m, PrimState m ~ s) => MutBranch s b a -> Ref s b -> (a -> (a, r)) -> m (Maybe r) -- | 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 s a) => MutBranch s [a] (a, [a])
--   consMB = constrMB (CLabel @":")
--   
constrMB :: forall ctor s b a. (Ref s b ~ GRef s b, GMutBranchConstructor ctor s (Rep b) a) => CLabel ctor -> MutBranch s b a -- | 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. data CLabel (ctor :: Symbol) CLabel :: CLabel (ctor :: Symbol) -- | Typeclass powering constrMB using GHC Generics. -- -- Heavily inspired by Data.Generics.Sum.Constructors. class (GMutable s f, Mutable s a) => GMutBranchConstructor (ctor :: Symbol) s f a | ctor f -> a -- | Useful type family to Ref m over every item in a -- type-level list -- --
--   ghci> :kind! MapRef IO '[Int, V.Vector Double]
--   '[ MutVar RealWorld Int, MVector RealWorld Double ]
--   
type family MapRef s as -- | MutBranch focusing on the nil case of a list nilMB :: Mutable s a => MutBranch s [a] () -- | MutBranch focusing on the cons case of a list consMB :: Mutable s a => MutBranch s [a] (a, [a]) -- | MutBranch focusing on the Nothing case of a Maybe nothingMB :: Mutable s a => MutBranch s (Maybe a) () -- | MutBranch focusing on the Just case of a Maybe justMB :: Mutable s a => MutBranch s (Maybe a) a -- | MutBranch focusing on the Left case of an Either leftMB :: (Mutable s a, Mutable s b) => MutBranch s (Either a b) a -- | MutBranch focusing on the Right case of an Either rightMB :: (Mutable s a, Mutable s b) => MutBranch s (Either a b) b -- | Class of monads which can perform primitive state-transformer actions class Monad m => PrimMonad (m :: Type -> Type) -- | State token type type family PrimState (m :: Type -> Type)