Timers in Idris
Our first example demonstrates how to use timers in Idris. 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.
import Data.IORef
import System.Concurrency
main : IO ()
main = do
-- Timers represent a single event in the future. Here,
-- we create a timer that will wait for 2 seconds.
timer1 <- fork $ do
sleep 2000 -- Sleep for 2 seconds (2000 milliseconds)
putStrLn "Timer 1 fired"
-- We wait for the timer to complete
wait timer1
-- If you just wanted to wait, you could have used
-- `sleep`. One reason a timer may be useful is
-- that you can cancel it before it fires.
-- Here's an example of that.
cancelFlag <- newIORef False
timer2 <- fork $ do
sleep 1000 -- Sleep for 1 second
cancelled <- readIORef cancelFlag
if not cancelled
then putStrLn "Timer 2 fired"
else pure ()
-- Simulate stopping the timer
writeIORef cancelFlag True
putStrLn "Timer 2 stopped"
-- Give timer2 enough time to fire, if it ever
-- was going to, to show it is in fact stopped.
sleep 2000 -- Sleep for 2 secondsIn this Idris example, we’re using the System.Concurrency module to simulate timers. We use fork to start asynchronous computations and sleep to introduce delays.
For the first timer, we simply fork a computation that sleeps for 2 seconds and then prints a message. We use wait to block until this computation completes.
For the second timer, we demonstrate how to “cancel” a timer. We use an IORef to hold a cancellation flag. The timer checks this flag before executing its action. We set the flag to simulate stopping the timer.
To run this program, save it as timers.idr and use the Idris compiler:
$ idris -o timers timers.idr
$ ./timers
Timer 2 stopped
Timer 1 firedThe first timer will fire ~2 seconds after we start the program, but the second timer’s action is prevented from executing due to our “cancellation” mechanism.
Note that Idris doesn’t have built-in timer functionality like Go, so we’ve simulated it using concurrency primitives. In a real-world scenario, you might want to use a more sophisticated timing library if available.