我试图从purescript调用navigator.geolocation.getCurrentPosition
javascript函数,但我遇到了两个问题。
在javascript中,它将使用类似的东西调用
navigator.geolocation.getCurrentPosition(function(position) { ... });
其中position是一个对象。
首先,我不知道返回类型应该是什么,因为它不返回任何内容,而是调用回调。
其次,我不知道回调使用什么类型,因为函数不能是纯的,因为它的结果不会被返回。
到目前为止我有
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之前也应该有一个回调参数。我只是不确定如何编写类型签名或实现它。
首先,我不知道返回类型应该是什么,因为它不返回任何内容,而是调用回调。
你已经正确地将返回类型识别为Unit
或{}
,但geolookup
函数本身是有效的,因此应该用Eff
类型构造函数包装。
其次,我不知道回调使用什么类型,因为函数不能是纯的,因为它的结果不会被返回。
所以让我们给回调一个合适的类型。作为一个有效的函数,像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的文章。