paf31 / purescript-book

Sources for the PureScript book
454 stars 370 forks source link

Chapter 8.17 - Mutable State: Modifications required to simulate and simulate' functions #114

Open sevanspowell opened 7 years ago

sevanspowell commented 7 years ago

Chapter 8.17 - Mutable State

For code to build, need to explicitly discard result of modifySTRef in the simulate function. Behaviour introduced in https://github.com/purescript/purescript/issues/1803 (I think).

That is, need to change this:

simulate :: forall eff h. Number -> Number -> Int -> Eff (st :: ST h | eff) Number
simulate x0 v0 time = do
  ref <- newSTRef { x: x0, v: v0 }
  forE 0 (time * 1000) \_ -> do
    modifySTRef ref \o ->
      { v: o.v - 9.81 * 0.001
      , x: o.x + o.v * 0.001
      }
    pure unit
  final <- readSTRef ref
  pure final.x

to this:

...
    _ <- modifySTRef ref \o ->
...

Also the simulate' function would not build because the type signatures of simulate and simulate' don't match:

simulate :: forall eff h. Number -> Number -> Int -> Eff (st :: ST h | eff) Number
simulate' :: Number -> Number -> Number -> Number
simulate' x0 v0 time = runPure (runST (simulate x0 v0 time))

time is an Int in simulate and Number in simulate'. I needed to convert time to a Int using Data.Int.round:

import Data.Int (round)

...

simulate' :: Number -> Number -> Number -> Number
simulate' x0 v0 time = runPure (runST (simulate x0 v0 (round time)))

but there might be better ways to do this.

By the way Phil, I'm really enjoying this book and it's (challenging) exercises. Thanks heaps!