
On 2015-01-08 at 18:11:22 +0100, John Lato wrote: [...]
evaluate is probably to be preferred if IO is available, similar to throw vs throwIO. However I think idioms with seq and ($!) are so common that they need to be supported too. After all, you may have just a 'Monad m' context.
One thing that always confused me is the semantics of seq/($!)/($!!) in something like foo = do { x <- getX; rnf x `seq` return x } as in my mental model, `;` or rather (>>=) combines two monadic actions (according to the monad-laws), into a combined monadic action "value" 'Monad m => m a', which then needs to be executed via some monad-runner to have any monadic effect and/or extract the result of type 'a'. But I don't see how the monad-laws tell me anything about when that `seq` is executed (is it evaluated at monadic combination time[1], or only lateron at monadic execution?). Otoh, in the IO-monad, 'evaluate' seems to be quite clear to me in its semantics: it forces WHNF on its argument at execution-time. [1]: what effects does "seq foo ()" perform? If the action was foo' = do { undefined `seq` return () } :: Monad m => m () then "seq foo' ()" will in fact diverge. So in that case, the `seq` is evaluated at monadic combination time; but otoh for foo'' = do { return undefined } :: Monad m => m () "seq foo'' ()" will (for a sane 'return') evaluate to '()' Cheers, hvr