[Haskell-beginners] Lazy variant of sequence (or other way to approach problem)
Ertugrul Söylemez
es at ertes.de
Thu Sep 27 01:45:08 CEST 2012
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.
>
> 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. What you want is unsafeLazySequenceIO, which uses
unsafeInterleaveIO under the hood, which is IO-specific. As always lazy
I/O is probably a bad idea and you should write a coroutine-based
combinator for that. The simplest way is the ad-hoc way:
pollEvent_ = do
ev <- pollEvent
case ev of
NoEvent -> pollEvent_
_ -> return ev
The coroutine-based method would look something like this:
import Control.Monad.Trans.Free -- from the 'free' package
newtype AppF a = AppF (Event -> a)
type App = FreeT AppF IO
Since FreeT is effectively just Coroutine from the monad-coroutine
package you can use that one instead with the 'Await Event' functor, but
the 'free' package provides a lot more useful instances. Your main loop
can then suspend to ask for the next event and the surrounding
application can provide the event in whatever way it wishes (for example
ignoring NoEvent):
myLoop = do
ev <- await
case ev of
Quit -> return ()
_ -> doSomethingWith ev
By the way, if your application is non-continuously rendered, which is
suggested by your ignoring of NoEvent, you shouldn't use pollEvent at
all. Rather you should use waitEvent, which blocks instead of returning
NoEvent. That way you don't waste precious CPU cycles. The pollEvent
action is meant for applications that are continuously rendered, where
you would e.g. perform drawing when you get NoEvent.
Hope this helps.
Greets,
Ertugrul
--
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20120927/b615eba6/attachment.pgp>
More information about the Beginners
mailing list