Skip to content

Offer stricter versions of AccumT #91

@sjshuck

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions