Edit: I changed my response after I took the time to understand what you meant.
Concur has a very uniform programming model where you do everything by composing widgets. `elm` is a widget. `render` also is a widget. As such both can perform arbitrary async effects, and they take place inside event handlers, or inside lifecycle methods like componentWillMount. Concur takes care of managing that for you.
So to log all actions to the console, you can add a logging call to `elm`.
elm render update = go
where go st = do
action <- render st
liftEffect (log ("Action - " <> show action))
go (update st action)
Meanwhile, the render function itself can be a widget which performs side effects -
view = do
evt <- button [onClick] [text "Click me"]
liftEffect (log "Button was clicked")
return evt
There are lots of examples of effects in the Concur repo - Take a look at some running examples here -