Mutate F# [<Struct>] Record

Viewed 83

This code shows how to make a function mutate its input - one of the things we come to F# to avoid.

type Age = { mutable n : int }
let printInside a = printfn "Inside = %d" a.n
let inside a =
    a.n <- a.n + 1
    a.n

let a = {n = 1}

printInside a //a = 1
inside a
printInside a //a = 2

That being said, how do I do the same bad thing with [<Struct>] Records? I suspect that ref or byref may be involved but I just can't seem to get it to work.

type [<Struct>] Age = { mutable n : int }
let printInside a = printfn "Inside = %d" a.n
let inside a =
    a.n <- a.n + 1
    a.n

let a = {n = 1}

printInside a //a = 1
inside a
printInside a //a = 2
2 Answers

The fundamental issue is that a mutable field can only be modified if the struct itself is mutable. As you noted, we need to use byref in the declaration of Age. We also need to make sure a is mutable and lastly we need to use the & operator when calling the function inside. The & is the way to call a function with a byref parameter.

type [<Struct>] Age = { mutable n : int }
let printInside a = printfn "Inside = %d" a.n
let inside (a : Age byref) =
    a.n <- a.n + 1
    a.n

let mutable a = {n = 1}

printInside a //a = 1
inside &a
printInside a //a = 2

Now that I get the pattern, here is a simple example (just an int instead of a struct record) of how to mutate values passed into a function:

let mutable a = 1
let mutate (a : byref<_>) = a <- a + 1
mutate &a
a //a = 2
Related