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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions