Skip to content

Offer stricter versions of AccumT #91

Description

@sjshuck

[original issue 89 by @treeowl]

AccumT is extremely lazy, much like lazy StateT. I suspect that for most purposes, what users actually want is a version that's strict in the accumulator value. That would correspond to instances (at least approximately) like the following:

instance (Monoid w, Functor m, Monad m) => Applicative (AccumT w m) where
    pure a  = AccumT $ \ !_ -> return (a, mempty)
    {-# INLINE pure #-}
    mf <*> mv = AccumT $ \ !w -> do
      (f, !w&#39;)  <- runAccumT mf w
      (v, !w&#39;&#39;) <- runAccumT mv (w `mappend` w&#39;)
      return (f v, w&#39; `mappend` w&#39;&#39;)
    {-# INLINE (<*>) #-}

instance (Monoid w, Functor m, Monad m) => Monad (AccumT w m) where
    m >>= k  = AccumT $ \ !w -> do
        (a, !w&#39;)  <- runAccumT m w
        (b, !w&#39;&#39;) <- runAccumT (k a) (w `mappend` w&#39;)
        return (b, w&#39; `mappend` w&#39;&#39;)
    {-# INLINE (>>=) #-}

I think it's also plausible that some users will want a version that's strict in the result pairs, but not in the accumulators. Would you be open to offering the totally strict version, and perhaps the pair-strict version?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions