[Haskell-beginners] Lazy variant of sequence (or other way to approach problem)

Chaddaï Fouché chaddai.fouche at gmail.com
Thu Sep 27 12:00:42 CEST 2012


On Thu, Sep 27, 2012 at 9:14 AM, Nathan Hüsken <nathan.huesken at posteo.de>wrote:

> On 09/27/2012 01:45 AM, Ertugrul Söylemez wrote:
> > Nathan Hüsken <nathan.huesken at posteo.de> wrote:
> >
> >> In my (SDL based) haskell program, I do:
> >>
> >> events <- liftM ( takeWhile (/= NoEvent)) $ sequence $ repeat
> >> pollEvent
> >>
> >> The execution of this never returns, I am guessing that is because
> >> sequence evaluation never stops.
>

Yes, which is why you should include the condition in the loop, the
standard library doesn't include facilities for that but the monad-loop
package has this function (amongst others) :

> unfoldWhileM :: Monad<http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Control-Monad.html#t:Monad>m => (a ->
Bool<http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Data-Bool.html#t:Bool>)
-> m a -> m [a]

which you could use as :

> events <- unfoldWhileM (=/ NoEvent) pollEvent

(note that if this is the only thing you use from this library, you may
just write this function for yourself, it is quite easy in the direct style
like the pollEvent_ proposed by Ertugrul)


> >>
> >> But if sequence would be lazy (and assuming pollEvent returns NoEvent
> >> at some point) this should stop, should it not?
> >> Is there a lazy variant of sequence? Or am I missing something here
> >> completely?
> >
> > The sequence function itself cannot be lazy, and there can't be a lazy
> > variant of it.
>
> I understand, that it is a bad Idea. But why is it impossible to have an
> lazy sequence? Why can it not wait with the execution of the action for
> the list elements to be evaluated?
>
>
Normally, with the normal semantics of monads, you can't have a lazy
sequence because it could mean that monad evaluation could be interspersed
in pure code without it being apparent (which is particularly dangerous
with IO) which is why you need to use unsafe functions to get this
unnatural result. It is also generally a bad idea for the same reason as
lazy IO is, to illustrate this in your particular case : you don't have
_any_ guarantee that it would work correctly : if you only start consuming
"events" a few seconds later, you wouldn't get the result from a few
seconds ago, you would get the current events... Maybe this doesn't happen
now in your application but can you be _sure_ that you'll never need to
stock those lists of events to consult them later on ?

-- 
Jedaï
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20120927/5647c5dd/attachment.htm>


More information about the Beginners mailing list