Here's a function I wrote in PureScript. It compiles with no errors or warnings. The function does some setting up to handle mouse movement:
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 and velocityRef are STRef variables that reference mutable variables. They are being passed in by a calling function.
And here's the compiled JavaScript version of the same code snippet:
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)();
};
};
};
This is the problem I'm facing: The point of this snippet is to call the rotateCube function with the newly calculated angle obtained from the mouse movement and stored in newAngle.
However, when I run this code in the browser, it doesn't do what I want it to do. I then tried debugging the JavaScript code and I discovered that the newAngle variable ends up having the value of
{ x: NaN, y: NaN }
After tracing the code I found out the reason was because the variable v5.x (which is angle.x in PureScript) has a value that is of Number type, but the variables v2 and v4.x (x and lastPos.x) have the following type
v2: Object[1]
0: 127
length: 1
instead of being a Number. The same thing happens in the case of y and lastPos.y. I'm guessing the addition of this with the Number type of angle.x results in NaN. But why is that happening? Why aren't x and lastPos.x turning out to be Numbers at runtime in javascript and instead look like these arrays?
I'm not sure if this is a clue or not, but the on function in Control.Monad.Eff.JQuery takes a function as an argument (in this case, moveHandler) that will be executed when the event occurs and that function should be of type
(JQueryEvent -> JQuery -> Eff (dom :: DOM | eff) a))
But inside moveHandler I have two side effects, one is DOM and the other is ST because of using readSTRef.
I actually tried explicitly declaring the type for moveHandler before it's definition like this
moveHandler :: forall e h. JQueryEvent -> JQuery -> Eff (dom :: DOM, st :: ST h | eff) Unit))
But this would always give me a Could not match type error, which is why I ended up just not mentioning an explicit type for moveHandler. Could this be a reason why the code isn't working? Is it not possible to have an ST effect also happening in the event handler callback function?
getPageXis wrong inpurescript-jquery. - Phil Freemanxandythat have the problem. EvenlastPos.xandlastPos.yend being an array instead ofNumbertype, but they get their values from thereadSTReffunction. Also worth mentioning, I have another fuction in my program that also usesreadSTRefbut over there the value is assigned normally so I'm really confused as to why this is happening only insidemoveHandler- George V.M.getPageXreturns jQuery instance instead of a Number - Yury Tarabanko