foldRecM is the stack-safe way to traverse_ an Array

If you are blowing the stack when doing traverse_ over an Array then you can use this stack-safe traverseRec_ function instead, written in terms of Data.Array.foldRecM

-- | Traverse an `Array`, performing some effects
-- | at each value, ignoring the final result. Stack-safe.
traverseRec_ 
  :: forall m a b
   . MonadRec m
  => (a -> m b)
  -> Array a
  -> m Unit
traverseRec_ f ta = Data.Array.foldRecM (\_ x -> void $ f x) unit ta

I kind of think traverseRec_ should be in a library, but I’m not sure which library.

Who can write traverseRec in terms of foldRecM as a stack-safe alternative to traverse?

-- | Traverse an `Array`, performing some effects 
-- | at each value and accumulating the result. Stack-safe.
traverseRec
  :: forall m a b
   . MonadRec m
  => (a -> m b)
  -> Array a
  -> m (Array b)
1 Like

Post about Stack-safe foldr Stack-safe default foldr?

Here is a stack-safe traverse Dissect.Class - purescript-dissect - Pursuit

Here is an implementation of stack-safe traverseRec based on What Nate told me about Array building

-- | Traverse an `Array`, performing some effects
-- | at each value and accumulating the result. Stack-safe.
traverseRec
  :: forall m a b
   . MonadRec m
  => (a -> m b)
  -> Array a
  -> m (Array b)
traverseRec f ta =
  Array.reverse <$> Array.fromFoldable <$> Array.foldRecM accum Nil ta
    where
      accum bs a = do
        b <- f a
        pure $ List.Cons b bs
1 Like