5

I am just starting to learn Purescript so I hope that this is not a stupid question.

Suppose that we have an object

a = {x:1,y:2}

an we want to change x to equal 2. As far as I can see if we use the ST monad we will have to copy the whole object in order to change the value. If the initial object is big this would be very inefficient. What is the right way to mutate objects in place?

Tzanko Matev
  • 259
  • 1
  • 5

1 Answers1

7

The ST monad is a fine approach, but depending on your use case, there may or may not be standard library functions for this.

The Data.StrMap module in purescript-maps defines a foreign type for homogeneous records with string keys, so if your values all have the same type, you could use Data.StrMap.ST to mutate your record in place.

If not, you should be easily able to define a function to update a record in place using ST and the FFI. The tricky bit is picking the right type. If you want to do something for a specific key, you could write a function

setFoo :: forall r a h eff. STRef h { foo :: a | r } -> a -> Eff (st :: ST h | eff) Unit

for example. Defining a generic setter would be more difficult without losing type safety. This is the trade-off made by Data.StrMap: you restrict yourself to a single value type, but get to use arbitrary keys.

Phil Freeman
  • 4,199
  • 1
  • 20
  • 15
  • Thank you for the answer. I guess you can't really do in-place modification in a generic way without having dependent types. – Tzanko Matev Sep 24 '15 at 09:08
  • 2
    I think polymorphic labels would be enough, and they're on the radar for a future compiler version, just not a definite proposal yet. – Phil Freeman Sep 24 '15 at 16:32