4
votes

I want to use setTimeout for animation in PureScript like this.

loop n =
  if n > 100
  then do
    return Unit
  else do
    print n
    timeout (loop n+1) 30

purescript-timers is no longer work in v0.7.

I don't have the slightest idea how to implement this.

2

2 Answers

3
votes

The simplest way is to define your own foreign import for setTimeout:

module SetTimeout where

foreign import data TIMEOUT :: !

foreign import timeout :: forall eff a. 
                               Int -> 
                               Eff (timeout :: TIMEOUT | eff) a -> 
                               Eff (timeout :: TIMEOUT | eff) Unit

In your foreign Javascript module, you can define setTimeout as follows:

"use strict";

// module SetTimeout

exports.timeout = function(millis) {
    return function(action) {
        return function() {
            setTimeout(action, millis);
        };
    };
};

You would be able to extend this to work with things like clearTimeout if needed.

Some other possible approaches:

2
votes

There are two ways:

  1. Use purescript-js-timers from purescript-contrib.

  2. Use purescript-aff (later').

I prefer the later, and here is an example:

import Control.Monad.Aff as Aff

update :: forall eff. Action -> State -> EffModel State Action (eff)
update MyAction myState = 
  { state: myState, effects: [ Aff.later' 1000 $ pure MyOtherAction ] }