Bit Connor wrote:
> computation is. And since it's all calls to map and filter et al., it's
> ...it's not immediately clear how to provide any feedback
> on how much longer there is to wait.
Andrew Coppin wrote:
> It seems unsafePerformIO is the way to go here.
> ...unsafeInterleaveIO
I disagree. The unsafe... functions are called that
for a reason, and their use should be highly discouraged,
except in cases where there is absolutely no other
reasonable way. I don't believe that this is one
of those cases.
A better approach is to use pure monads. Instead of
f :: ... -> a
write functions whose type is something like
f :: ... -> MyMonad a
where MyMonad is defined in one and only
one place in your program. Or, better yet,
polymorphic things like
f :: Monad m => ... -> m a
f :: MyMonadClass m => ... -> m a
Then when you later need to add something
like progress indicators, you just add that
to the capabilities of your monad, and add
some updateProgress calls to your functions.
By using "do" notation wisely, you can
keep your abstractions just as clear as they
were, and cleanly separated from the progress logic.
Other things you may need to add later in
real-world programs are exception handling,
logging, trace, etc. All of these are easy if you
started out in a monad.
-Yitz