Timers in PureScript
Our first example demonstrates the use of timers in PureScript. Timers allow us to execute code at some point in the future or repeatedly at some interval. We’ll focus on timers in this example.
module Main where
import Prelude
import Effect (Effect)
import Effect.Console (log)
import Effect.Timer (Timer, setTimeout, clearTimeout)
import Effect.Aff (Aff, launchAff_, delay)
import Effect.Class (liftEffect)
import Data.Time.Duration (Milliseconds(..))
main :: Effect Unit
main = do
-- Timers represent a single event in the future. You
-- tell the timer how long you want to wait, and it
-- will execute a callback after that time. This timer will wait 2 seconds.
timer1 <- setTimeout 2000 (log "Timer 1 fired")
-- We use `launchAff_` to run an asynchronous effect that waits for 2 seconds
-- This is similar to blocking on a channel in the original example
launchAff_ do
delay (Milliseconds 2000.0)
liftEffect $ log "Timer 1 fired"
-- If you just wanted to wait, you could have used
-- `delay`. One reason a timer may be useful is
-- that you can cancel the timer before it fires.
-- Here's an example of that.
timer2 <- setTimeout 1000 (log "Timer 2 fired")
-- We immediately stop timer2, so it should never fire
clearTimeout timer2
log "Timer 2 stopped"
-- Give timer2 enough time to fire, if it ever
-- was going to, to show it is in fact stopped.
launchAff_ $ delay (Milliseconds 2000.0)
To run this program, you would typically compile it with the PureScript compiler and then execute the resulting JavaScript. The exact commands might vary depending on your project setup, but it could look something like this:
$ spago build
$ node -e "require('./output/Main').main()"
Timer 1 fired
Timer 2 stopped
The first timer will fire approximately 2 seconds after we start the program, but the second should be stopped before it has a chance to fire.
In this PureScript version, we use the Effect.Timer
module to create and manage timers. The setTimeout
function is used to create a timer, and clearTimeout
is used to cancel it. We use launchAff_
and delay
from the Effect.Aff
module to handle asynchronous operations, which is similar to how channels are used in the original example for synchronization.
Note that PureScript, being a purely functional language, handles side effects and asynchronous operations differently from imperative languages. The use of Effect
and Aff
types helps manage these operations in a pure and composable way.