Reflex is a simple reaction time tester. Only the Return key is used in interaction with the program. When pressing Return for the first time, the user is instructed to Wait...; after a few seconds, the program says Go! and the user must strike Return again as fast as possible. The elapsed time is displayed and the test can be repeated.

Here is the program:

module Reflex where

import POSIX
import RandomGenerator

data State = Idle | Waiting Msg | Counting

format t = show (secOf t) ++ '.' : fracs ++ " secs"
  where n  = microsecOf t `div` 10000
        fracs = if n<10 then '0':show n else show n 
reflex env = class
   print str = env.stdout.write (str ++ "\n")

   tmr = new timer
   gen = new baseGen (microsecOf env.startTime)

   state := Idle
   enter _ = action
      case state of
        Idle ->         r <-
                        waitingTime = sec 2 + millisec (r `mod` 2000)
                        msg <- after waitingTime action
                           print "Go!"
                           state := Counting 
                        print "Wait..."
                        state := Waiting msg
        Waiting msg ->  abort msg
                        print "Cheat!!!"
                        state := Idle

        Counting ->     t <- tmr.sample
                        print (format t)
                        state := Idle

   result action
       env.stdin.installR enter
       print "Press return to start"

root = newRoot reflex

Comments to the code: