Updating Model from the effect interpreter in purescript-spork v.1.0.0

I can’t see how I can hook back into the update loop when intrepreting an effect in purescript-spork v.1.0.0. Basically I want to update my model, run an effect (e.g. a network request) then feed the result back into update. I suspect it might be via subscriptions? Any help would be much appreciated!

I suspect it might be via subscriptions

Effects and subscriptions are essentially the same thing, they are just called at different times. Effects are produced by update, and subscriptions are a rendering artifact. So they are both have the same ability to produce updates.

The key to feeding results back into update, is using a function in your Effect data type. If we were to write an example effect for getting a random integer it would look like:

data Random a
  = RandomInt (Int -> a)

Note that the argument to RandomInt is a function Int -> a. To use this, you would just put whatever Action you want into it:

data MyAction
  = SetValue Int
  | GetNewValue

update model = case _ of
  GetNewValue ->
    { model
    , effects: App.lift (RandomInt SetValue)
    }
  SetValue value ->
    App.purely $ model { value = value }

Then to feed the result back into your app, you pattern match on the effect and provide the value to the function embedded in it. The simplest way is with liftNat which just runs a natural transformation.

runRandom :: Random ~> Effect
runRandom = case _ of
  RandomInt reply -> do
    int <- randomInt 0 100
    pure (reply int)

main = do
  ...
  inst <-
    App.makeWithSelector
      (liftNat runRandom `merge` never)
      app
      "#app"

There are different ways you can run your interpreter. Probably the most common would be with Aff, and you can use throughAff to do that. But liftCont is the most general, and gives you a callback you can invoke as many times as you need per “instruction”.

2 Likes

That’s awesome, thanks! It’s nice to have a lightweight alternative to Halogen for smaller apps. Thanks for sharing!