to correctly handle GUI events you need to use the original thread allocated to your process to check for events and to call the Cocoa framework functionality.
I looked at the threading documentation in Control.Concurrent for GHC and it's not clear to me if this is even possible with GHC without restricting to the non-threaded RTS.
The 'main' thread in GHC is the bound thread initially allocated to the process. You can easily establish an event-loop in the main thread, and feed events from other threads. Consider using Control.Concurrent.Chan.
If you need feedback, things get a bit trickier because you'll have special cases based on whether you're starting in the main thread.
Regards,
Dave