使用purescript的FFI调用带回调的js函数
Calling js functions with callbacks using purescript's FFI
我正在尝试从纯脚本调用 navigator.geolocation.getCurrentPosition
javascript 函数,但我遇到了两个问题。
在 javascript 中,它会被称为
navigator.geolocation.getCurrentPosition(function(position) { ... });
其中 position 是一个对象。
首先,我不知道 return 类型应该是什么,因为它没有 return 任何东西,而是调用回调。
其次,我不知道回调使用什么类型,因为函数不能是纯函数,因为它的结果不会被 returned。
到目前为止我有
foreign import geolookup "function (callback) {\
navigator.geolocation.getCurrentPosition(callback);
\}" :: forall eff a. Eff (geolookup :: GeoLookup | eff) {}
geolookup \position -> ...
所以这里我的外部函数的类型签名是 forall eff a. Eff (geolookup :: GeoLookup | eff) {}
,但是我知道在 Eff 之前也应该有一个回调参数。我只是不确定如何编写或实现类型签名。
Firstly, I don't know what the return type should be as it doesn't return anything, but instead calls a callback.
您已经正确地将 return 类型识别为 Unit
或 {}
,但是 geolookup
函数本身是有效的,因此应该用 Eff
类型构造器。
Secondly, I don't know what type to use for the callback, as the function can't be pure as it's result won't be returned.
所以让我们给回调一个合适的类型。作为一个有效的函数,像 a -> Eff _ b
这样的东西是有意义的,并且为了避免行中的重复标签,我们不得不在我们的行中包含 GeoLookup
效果。所以让我们给回调类型 Position -> Eff (geolookup :: GeoLookup | eff) Unit
.
那么我们函数的完整类型就变成了
foreign import data Position :: *
geolookup :: forall eff. (Position -> Eff (geolookup :: GeoLookup | eff) Unit) ->
Eff (geolookup :: GeoLookup | eff) Unit
在 FFI 中,我们可以包装 navigator.geolocation.getCurrentPosition
调用以与此类型兼容。使用 0.7 编译器的 FFI 风格:
exports.geolookup = function(callback) {
return function() { // Outer Eff
navigator.geolocation.getCurrentPosition(function(p) {
callback(p)(); // Extra () due to inner Eff
});
};
};
此时,您可能希望研究 ContT
或 Aff
等类型,以更可组合的方式包装您的函数。
您可能想阅读有关 how to use the Eff monad 的文章。
我正在尝试从纯脚本调用 navigator.geolocation.getCurrentPosition
javascript 函数,但我遇到了两个问题。
在 javascript 中,它会被称为
navigator.geolocation.getCurrentPosition(function(position) { ... });
其中 position 是一个对象。
首先,我不知道 return 类型应该是什么,因为它没有 return 任何东西,而是调用回调。
其次,我不知道回调使用什么类型,因为函数不能是纯函数,因为它的结果不会被 returned。
到目前为止我有
foreign import geolookup "function (callback) {\
navigator.geolocation.getCurrentPosition(callback);
\}" :: forall eff a. Eff (geolookup :: GeoLookup | eff) {}
geolookup \position -> ...
所以这里我的外部函数的类型签名是 forall eff a. Eff (geolookup :: GeoLookup | eff) {}
,但是我知道在 Eff 之前也应该有一个回调参数。我只是不确定如何编写或实现类型签名。
Firstly, I don't know what the return type should be as it doesn't return anything, but instead calls a callback.
您已经正确地将 return 类型识别为 Unit
或 {}
,但是 geolookup
函数本身是有效的,因此应该用 Eff
类型构造器。
Secondly, I don't know what type to use for the callback, as the function can't be pure as it's result won't be returned.
所以让我们给回调一个合适的类型。作为一个有效的函数,像 a -> Eff _ b
这样的东西是有意义的,并且为了避免行中的重复标签,我们不得不在我们的行中包含 GeoLookup
效果。所以让我们给回调类型 Position -> Eff (geolookup :: GeoLookup | eff) Unit
.
那么我们函数的完整类型就变成了
foreign import data Position :: *
geolookup :: forall eff. (Position -> Eff (geolookup :: GeoLookup | eff) Unit) ->
Eff (geolookup :: GeoLookup | eff) Unit
在 FFI 中,我们可以包装 navigator.geolocation.getCurrentPosition
调用以与此类型兼容。使用 0.7 编译器的 FFI 风格:
exports.geolookup = function(callback) {
return function() { // Outer Eff
navigator.geolocation.getCurrentPosition(function(p) {
callback(p)(); // Extra () due to inner Eff
});
};
};
此时,您可能希望研究 ContT
或 Aff
等类型,以更可组合的方式包装您的函数。
您可能想阅读有关 how to use the Eff monad 的文章。