
On Fri, Nov 29, 2013 at 1:32 PM, David Luposchainsky < dluposchainsky@googlemail.com> wrote:
On 29.11.2013 13:19, Twan van Laarhoven wrote:
In the same vein as strict fmap, does a strict (<*>) make sense as well?
I think this brings up a good point: strictness annotations may make sense in multiple other scenarios, not just for fmap. Can't we encapsulate similar functionality in a separate function first, wait for it to settle, and then introduce infix versions of it if really necessary?
What about
seqM :: Monad m => m a -> m a seqM m = m >>= (return $!)
This would allow local definitions of
f <$!> x = seqM (f <$> x) mf <*!> mx = seqM (mf <*> mx)
until the dust settles. If <$!> is really used in abundance, then add <$!> as an infix.
I think this is a good idea. We still need to think about how to make it clear to users when they need to force things when writing functorial (sp?)/applicative/monadic code. It's quite easy to introduce additional thunks there as expressions are often pushed inside a lazy data type (e.g. the state monad pushes the value inside a lazy tuple). If you look at e.g. the applicative APIs or some code that use them (e.g. attoparsec), it's not obvious that you can shoot yourself in the foot pretty easily by introducing too many thunks and thus use more space than needed. I ran into this in practice when working with attoparsec. If you use e.g. the provided sepBy combinator, you end up with a list of many thunks in it. We ended up adding strict versions of basically all the combinators to work around this. -- Johan