# Beautiful Mutable Values

**Mutability can be awesome!**

Take back the power of **mutable objects** with all the **safety** and explicit
state of Haskell. Associate and generate "piecewise-mutable" versions for your
composite data types in a composable and automatic way. Think of it like a
"generalized `MVector`

for all ADTs". It also leverages GHC Generics to make
working with piecewise mutability as simple as possible.

Making piecewise updates on your giant composite data types (like artificial neural networks or game states in your game loop) got you down because they require re-allocating the entire value? Tired of requiring a full deep copy every time you make a small change, and want to be able to build mutable versions of your types automatically in composable ways? This is the package for you.

```
data MyType = MT
{ mtInt :: Int
, mtDouble :: Double
, mtVec :: V.Vector Double
}
deriving (Show, Generic)
instance Mutable s MyType where
type Ref s MyType = GRef s MyType
```

The type `Ref s MyType`

is now a "mutable `MyType`

", just like how ```
MVector s
a
```

is a "mutable `Vector a`

". You have:

```
thawRef :: MyType -> ST s (Ref s MyType)
freezeRef :: Ref s MyType -> ST s MyType
```

(These actions are in `ST`

, the mutable memory monad that comes with GHC. The
real types of these are more polymorphic and are generalized to work for all
mutable monads with `PrimMonad`

instance.)

You can use `thawRef`

to allocate a mutable `MyType`

that essentially consists
of a mutable `Int`

, a mutable `Double`

, and a mutable `Vector`

(an `MVector`

)
all tupled together. You can edit these pieces in isolation, and then
`freezeRef`

it all back together:

```
doStuff :: MyType -> MyType
doStuff x = runST $ do
r <- thawRef x
replicateM_ 1000 $ do
-- modify the Int in `mtInt`
modifyPart (fieldMut #mtInt) r (+ 1)
-- the `mtVec` field is now an MVector
withField #mtVec r $ \v ->
MV.modify v (+1) 0
freezeRef r
```

```
doStuff $ MT 0 19.3 (V.fromList [1..12]) =>
MT {mtInt = 1000, mtDouble = 19.3, mtVec = [1001.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0]}
```

If you were to do this normally with pure values, this would be extremely
expensive, especially if `mtVec`

is a huge vector --- it would require copying
every item in the entire vector every step, being *O(n * l)* , with *n* number
of repetitions and *l* length of vector and number of fields. With mutable
vectors and mutable cells, this now becomes *O(n + l)*.

The main motivation for this library is to implement *automatically derivable*
piecewise-mutable references for the purposes of mutation-heavy algorithms,
like artificial neural networks. In the end, you're able to have an Artificial
Neural Network (which can have huuuuge vectors) and being able to do piecewise
updates on them (automatically) without having to copy over the entire network
every training step.

There is also support for mutable sum types, as well. Here is the automatic
definition of a *mutable linked list*:

```
data List a = Nil | Cons a (List a)
deriving (Show, Generic)
infixr 5 `Cons`
instance Mutable s a => Mutable s (List a) where
type Ref s (List a) = GRef s (List a)
```

We can write a function to "pop" out the top value and shift the rest of the list up:

```
popStack
:: Mutable s a
=> Ref s (List a)
-> ST s (Maybe a)
popStack xs = do
c <- projectBranch (constrMB #_Cons) xs
forM c $ \(y, ys) -> do
o <- freezeRef y
moveRef xs ys
pure o
```

```
runST $ do
r <- thawRef $ 1 `Cons` 2 `Cons` 3 `Cons` Nil
y <- popStack r
(y,) <$> freezeRef r =>
(Just 1,Cons 2 (Cons 3 Nil))
```

Check out **the getting started page**, or the **Haddock
Documentation** to jump right in! You can also read my introductory
blog post about the motivations for this library and things I learned
while developing it.