Debugging my event handler for the mouse move event, I wrote this code:
unless (scrollDelta == Tuple 0 0) $ trace (show scrollDelta) \_ -> do ...
And I get console output
Tuple 0 0
The idea behind this is to save a difference in the mouse position whenever the user moves the mouse with the first mouse button pressed.
Is this a compiler bug?
My workaround is to change the type of scrollDelta to Maybe (Tuple Int Int) where Nothing represents "no mouse movement while button pressed" instead of Tuple 0 0, which works.
Your problem is the difference between evaluation and execution.
When you write something like:
contrary to your intuition, that does not actually print anything to console. Instead, this creates an "action", which has to be "executed" at some later point, and it's only then that it will print something to the console.
Conversely, same action can actually be "executed" several times, and thus produce multiple effects:
In the above example, evaluation happens once, but execution - three times.
The way
unlessworks, it takes aBooleanvalue and an "action", and it returns another "action":When you execute the action
dontPrintFoo, it will be the action returned byunless, which will examine theBooleanparameter and choose not to execute the actionprintFoo.But say you have a bit more complicated scenario:
Here, both parameters of
unlessmust be "evaluated" (but not "executed"!) before they are passed tounless. This means that the value ofquxand the result ofif/thenis calculated before callingunless. But the resulting action would be executed later, when the whole result is called frommain.But
traceis special. Magic. Even though it produces an effect (printing to console), the compiler thinks it's a pure function. Like2 + 3or likeif qux then foo else bar. It's done this way for debugging convenience: so that you can insert tracing in pure, non-effectful code.This means that
traceis evaluated at "evaluation" time, not "execution". Which means that it's evaluated beforeunlessis even called, and therefore it's evaluated regardless of whether theBooleanparameter istrueorfalse.If you want the tracing to only work when
unlessdecided to execute the action, trytraceM: