纯脚本信号在时间开始时重复开始

Purescript signal repeatedly starting at beginning of time

我正在用 Purescript 构建游戏,使用 purescript-signal,其中包括移动。用户按下 left/right 键移动 left/right。最小代码如下。

看起来 purescript 每一步都在评估 "from the beginning of time" 的信号,这让我感到困惑。比如我一开始一直按右键,输出就是

m: 0
m: 0
m: 1
m: 0
m: 1
m: 2
m: 0
m: 1
m: 2
m: 3

而不是

m: 0
m: 1
m: 2
m: 3

如我所料。我该如何解决这个问题?

module SimpleMove where

import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Functor
import Data.Int
import Signal (Signal, runSignal, foldp, sampleOn, map2)
import Signal.DOM (keyPressed)
import Signal.Time (Time, second, every)
import Partial.Unsafe (unsafePartial)

--MODEL
type Model = Int

step :: forall e. Partial => Int -> Eff (console :: CONSOLE | e) Model -> Eff (console :: CONSOLE| e) Model
step dir m' = 
  do
    m <- m'
    log ("m: " <> (show m))
    pure (m + dir)

--SIGNALS
inputDir :: Eff _ (Signal Int)
inputDir = 
    let 
        f = \l r -> if l 
                    then -1 
                    else if r
                         then 1
                         else 0
    in
      map2 f <$> (keyPressed 37) <*> (keyPressed 39)

input :: Eff _ (Signal Int)
input = sampleOn (every second) <$> inputDir

--MAIN
main :: Eff _ Unit
main =
    unsafePartial do
      dirSignal <- input
      let game = foldp step (pure 0) dirSignal
      runSignal (map void game)

如果您像这样更改 mainstep,您将获得预期的结果:

main :: Eff _ Unit
main = do
      dirSignal <- input
      let game = foldp step 0 dirSignal
      runSignal (map render game)

step :: forall e. Int -> Model -> Model
step dir m = m + dir

render :: forall e. Model -> Eff (console :: CONSOLE| e) Unit
render m = logShow m