代码之家  ›  专栏  ›  技术社区  ›  George V.M.

PureScript函数在运行时给出错误的类型

  •  1
  • George V.M.  · 技术社区  · 7 年前

    这是我用PureScript编写的函数。它编译时没有错误或警告。该函数进行一些设置以处理鼠标移动:

    startMouseHandlers :: forall h e. STRef h {x::Number, y::Number}
      -> STRef h {x::Number, y::Number}
      -> Eff (dom :: DOM, st :: ST h | e) Unit
    startMouseHandlers angleRef velocityRef = do
      lastMousePos <- newSTRef {x: 0.0, y: 0.0}
      body <- JQuery.body
      let
        moveHandler event jq = do
        x <- getPageX event
        y <- getPageY event
        lastPos <- readSTRef lastMousePos
        angle <- readSTRef angleRef
        let newAngle = {
              x: angle.x + x - lastPos.x,
              y: angle.y + y - lastPos.y
            }
        rotateCube angleRef newAngle
        void $ writeSTRef lastMousePos {x: x, y: y}
      on "mousemove" movehandler body
    

    angleRef velocityRef STRef 引用可变变量的变量。它们由调用函数传入。

    var startMouseHandlers = function (angleRef) {
          return function (velocityRef) {
          return function __do() {
              var v = Control_Monad_ST.newSTRef({
                  x: 0.0, 
                  y: 0.0
              })();
              var v1 = Control_Monad_Eff_JQuery.body();
              var moveHandler = function (event) {
                  return function (jq) {
                      return function __do() {
                          var v2 = Control_Monad_Eff_JQuery.getPageX(event)();
                          var v3 = Control_Monad_Eff_JQuery.getPageY(event)();
                          var v4 = Control_Monad_ST.readSTRef(v)();
                          var v5 = Control_Monad_ST.readSTRef(angleRef)();
                          var newAngle = {
                              x: (v5.x + v2) - v4.x, 
                              y: (v5.y + v3) - v4.y
                          };
                          rotateCube(angleRef)(newAngle)();
                          return Data_Functor["void"](Control_Monad_Eff.functorEff)(Control_Monad_ST.writeSTRef(v)({
                              x: v2, 
                              y: v3
                          }))();
                      };
                  };
              };
              return Control_Monad_Eff_JQuery.on("mousemove")(moveHandler)(v1)();
          };
          };
      };
    

    这就是我面临的问题:这段代码的重点是调用 rotateCube newAngle .

    然而,当我在浏览器中运行这段代码时,它并没有达到我想要的效果。然后我试着调试JavaScript代码,发现 变量的值为

    { x: NaN, y: NaN }
    

    跟踪代码后,我发现原因是变量 v5.x angle.x 在PureScript中)的值为 Number 类型 变量 v2 v4.x ( x lastPos.x )具有以下类型

    v2: Object[1]
      0: 127
      length: 1
    

    而不是成为一个 y lastPos.y 类型 结果 NaN x 结果是 在javascript中运行时的,而不是看起来像这些数组?

    我不确定这是否是一个线索,但 on Control.Monad.Eff.JQuery moveHandler

    (JQueryEvent -> JQuery -> Eff (dom :: DOM | eff) a))
    

    移动处理程序 DOM 另一个是 ST 因为使用 readSTRef

    实际上,我尝试显式声明 移动处理程序 在这样定义之前

    moveHandler :: forall e h. JQueryEvent -> JQuery -> Eff (dom :: DOM, st :: ST h | eff) Unit))
    

    但这总会给我一个 Could not match type 错误,这就是为什么我最后没有提到 装货单

    1 回复  |  直到 7 年前
        1
  •  0
  •   George V.M.    7 年前

    正如菲尔·弗里曼和尤里·塔拉班科在评论中所建议的那样,事实证明 getPageX/Y 在里面 purescript-jquery 返回了错误的类型。它现在已经被更正,在更新包之后,程序按原样执行 newAngle

    虽然返回类型不正确 getPageX/Y 解释原因 x y lastPos.x lastPos.y 也是不正确的类型,即使它们是由 readSTRef .直到现在我才意识到我愚蠢的大脑没有把它想透。 lastPos 而且 getPageX/Y