1
votes

I think I'm close to what I want, though I suspect I'm not understanding how thaw / TH Region works.

Here is what I'm trying to implement (at least roughly)

modifyPerIndex :: forall t a. Foldable t => t (Tuple Int (a -> a)) -> Array a -> Array a
modifyPerIndex foldableActions array = run do
  mutableArray <- thaw array
  let actions = fromFoldable foldableActions
  foreach actions (\(Tuple index action) -> modify index action mutableArray)
  freeze mutableArray

This is sort of how I imagine updateAtIndices works. I suppose I could write modifyPerIndex to use updateAtIndices by reading in the values, applying the (a -> a) and mapping the result into a list of Tuples to be sent to updateAtIndices.

I'm curious how to do it this way though.

In the code above modify returns ST h Boolean, which I'd like to change into ST h Unit. That's where I'm lost. I get that h here is a constraint put on mutable data to stop it from leaving run, what I don't understand is how to use that.

1

1 Answers

2
votes

There are a few options. But it has nothing to do with h. You don't have to "use" it for anything, and you don't have to worry about it at all.

First, the most dumb and straightforward approach - just bind the result to an ignored variable and then separately return unit:

foreach actions \(Tuple index action) -> do
  _ <- modify index action mutableArray
  pure unit

Alternatively, you can use void, which does more or less the same thing under the hood:

foreach actions \(Tuple index action) -> void $ modify index action mutableArray

But I would go straight for for_, which is the same as foreach, but works for any monad (not just ST) and ignores individual iterations' return values:

for_ actions \(Tuple index action) -> modify index action mutableArray