我试图navigator.geolocation.getCurrentPosition从purescript 调用javascript函数,但我遇到了两个问题.
在javascript中,它将使用类似的东西调用
navigator.geolocation.getCurrentPosition(function(position) { ... });
Run Code Online (Sandbox Code Playgroud)
其中position是一个对象.
首先,我不知道返回类型应该是什么,因为它不返回任何内容,而是调用回调.
其次,我不知道回调使用什么类型,因为函数不能是纯的,因为它的结果不会被返回.
到目前为止我有
foreign import geolookup "function (callback) {\
navigator.geolocation.getCurrentPosition(callback);
\}" :: forall eff a. Eff (geolookup :: GeoLookup | eff) {}
geolookup \position -> ...
Run Code Online (Sandbox Code Playgroud)
所以这里我的外部函数的类型签名是forall eff a. Eff (geolookup :: GeoLookup | eff) {},但是我知道在Eff之前也应该有一个回调参数.我只是不确定如何编写类型签名或实现它.
我有来自purescript-express的以下代码(但问题更为一般).
setHandler :: forall e. Handler e
setHandler = do
idParam <- getRouteParam "id"
send "Yeah! "
appSetup :: forall e. App e
appSetup = do
get "/set/:id" setHandler
Run Code Online (Sandbox Code Playgroud)
setHandler需要具有get定义为的给定签名
> :t get
forall e r.
(RoutePattern r) => r
-> HandlerM ( express :: EXPRESS | e ) Unit
-> AppM ( express :: EXPRESS | e ) Unit
Run Code Online (Sandbox Code Playgroud)
但是现在我想在其中使用以下功能 setHandler
getPointsSet :: forall f. String -> Aff ( fs :: FS | f ) Foobar …Run Code Online (Sandbox Code Playgroud) 我正在"使用示例的PureScript"一书中进行分配,以使用递归来计算数组中偶数项的数量.
这是我写的代码
isEven :: Int -> Boolean
isEven 0 = true
isEven 1 = false
isEven n = isEven(n - 2)
countEven :: List Int -> Int
countEven list =
if null list
then 0
else
if isEven(unsafePartial (head list))
then 1
else 0 + countEven(unsafePartial (tail list))
Run Code Online (Sandbox Code Playgroud)
我收到一条错误消息说
Error found:
in module Main
at src/Main.purs line 74, column 17 - line 74, column 42
Could not match type
Maybe Int
with type
Int
while checking that type t0
is …Run Code Online (Sandbox Code Playgroud) 如何正确调用/定义不返回任何内容的外部函数。我究竟做错了什么?
渲染器.purs:
module Renderer where
import Prelude
import Effect (Effect)
foreign import renderMd :: String -> Effect Unit
Run Code Online (Sandbox Code Playgroud)
渲染器.js:
var md = require('markdown-it')();
exports.renderMd = function(str) {
document.body.append( md.render(str) );
}
Run Code Online (Sandbox Code Playgroud)
最后调用:
import React.Basic.DOM as R
import React.Basic.DOM.Events (targetValue)
import React.Basic.Events as Events
R.textarea
{ onChange: Events.handler targetValue $ maybe (pure unit) renderMd
}
Run Code Online (Sandbox Code Playgroud)
编译正常,但给出:
Uncaught TypeError: cb(...) is not a function
Run Code Online (Sandbox Code Playgroud)
在可能是 purescript-react-basic 的定义中handler,编译:
var handler = function (v) {
return function (cb) {
return function ($22) …Run Code Online (Sandbox Code Playgroud) 我正在致力于在 Purescript 中构建一个加密套利机器人,主要是为了了解函数式编程范例。作为一名 JS 程序员,我发现 Purescript 的错误消息非常难以解释。目前,在尝试使用 Affjax 库发出 http 请求时,我遇到了“TypesDoNotUnify”错误。我的代码如下所示:
\nimport Affjax.ResponseFormat (ResponseFormat(..))\nimport Affjax.ResponseFormat as ResponseFormat\nimport Data.Argonaut.Core (Json, fromString, stringify)\nimport Data.Either (Either(..))\nimport Data.HTTP.Method (Method(..))\nimport Effect (Effect)\nimport Effect.Aff (Aff, launchAff_)\nimport Effect.Console (log)\nimport Node.Express.App (App, listenHttp, get)\nimport Node.Express.Response (send)\nimport Node.HTTP (Server)\nimport Node.HTTP.Client (method)\n\nmakeQuoteRequest :: String -> String -> String -> String\nmakeQuoteRequest fromAddress toAddress amount = "https://api.1inch.exchange/v3.0/137/quote?fromTokenAddress=" <> fromAddress <> "&toTokenAddress=" <> toAddress <> "&amount=" <> amount\n\nsendQuoteRequest :: Either Error Unit\nsendQuoteRequest = launchAff_ do\n result <- AX.request(AX.defaultRequest {\n url = makeQuoteRequest …Run Code Online (Sandbox Code Playgroud) 我需要为记录类型定义一个简单的类型类和实例:
class Codable param where
getCodec :: Codec param
type Obj = { id :: String }
instance Codable Obj where
getCodec = objCodec
Run Code Online (Sandbox Code Playgroud)
尽管在定义记录类型的实例时出现错误:
Type class instance head is invalid due to use of type
( id :: string
)
All types appearing in instance declarations must be of the form T a_1 .. a_n, where each type a_i is of the same form, unless the type is fully determined by other type class arguments via functional dependencies.
Run Code Online (Sandbox Code Playgroud)
但这个消息对我来说听起来很神秘。有人可以详细说明吗?在这种情况下该怎么办?
PureScript 有条件三元运算符吗?
如果没有,是否可以使用其他语言结构来模拟?
无论如何,是否可以更优雅地编写以下函数?
我可以看到一些模式,但不确定如何抽象它们或如何找到一种更简单的编写函数的方法。
type HasRemainder = Boolean
tomorrow :: Date -> Date
tomorrow date = unsafePartial $ canonicalDate y (fst m) (fst d)
where d :: Tuple Day HasRemainder
d = case toEnum $ 1 + fromEnum (day date) of
Just v -> Tuple v false
Nothing -> Tuple (unsafePartial $ fromJust $ toEnum 1) true
m :: Tuple Month HasRemainder
m = if snd d then
case toEnum $ 1 + fromEnum (month date) of
Just v -> Tuple v …Run Code Online (Sandbox Code Playgroud) 给出一个元素列表:
xs = [a, b, c, d, ... z]
Run Code Online (Sandbox Code Playgroud)
其中a, b, cetc是任意值的占位符.我想实现一个adjacents :: [a] -> [(a, a)]生成的函数
adjacentValues = [(a, b), (b, c), (c, d), ... (y, z)]
Run Code Online (Sandbox Code Playgroud)
在Haskell中,递归定义相当简洁:
adjacents :: [a] -> [(a, a)]
adjacents (x:xs) = (x, head xs) : adjacents xs
adjacents [] = []
Run Code Online (Sandbox Code Playgroud)
Purescript有点冗长:
adjacents :: forall a. List a -> List (Tuple a a)
adjacents list = case uncons list of
Nothing -> []
Just {head: x, tail: xs} -> …Run Code Online (Sandbox Code Playgroud) 尝试为罗马数字创建构造函数:
data RomanDigit a = M | D | C | L | V | I
newRomanDigit :: Int -> RomanDigit
newRomanDigit 1000 = M
newRomanDigit 500 = D
Run Code Online (Sandbox Code Playgroud)
获取错误消息:
in module UserMod
at src\UserMod.purs line 81, column 1 - line 81, column 35
Could not match kind
Type
with kind
Type -> Type
while checking the kind of Int -> RomanDigit
in value declaration newRomanDigit
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
免责声明:我使用的是 PureScript,但也添加了 Haskell 标签,因为我认为这在两种语言中的行为方式可能相同,而且 Haskell 社区更大。
我想从数组中反复选择一个随机元素。每次我都希望有一个新的随机选择,但重复调用时的值总是相同的。似乎随机函数每次运行程序只评估一次。
这在后续调用中始终返回相同的名称:
import Data.Array (length, unsafeIndex)
import Effect.Random (randomInt)
import Effect.Unsafe (unsafePerformEffect)
import Partial.Unsafe (unsafePartial)
pick :: forall a. Array a -> a
pick arr = unsafePartial $ unsafeIndex arr i where
i = unsafePerformEffect $ randomInt 0 (length arr - 1)
name :: String
name = pick names
Run Code Online (Sandbox Code Playgroud)
使用此解决方法,它每次都会返回一个新的随机选择:
import Data.Array (length, unsafeIndex)
import Effect.Random (randomInt)
import Effect.Unsafe (unsafePerformEffect)
import Partial.Unsafe (unsafePartial)
pick :: forall a. Array a -> a
pick …Run Code Online (Sandbox Code Playgroud) 我可以像这样替换 do-block 吗:
do
...
pure ...
Run Code Online (Sandbox Code Playgroud)
其中最后一行是“纯粹”的东西,带有这样的 ado 块:
ado
...
in ...
Run Code Online (Sandbox Code Playgroud)
?
我知道do只需要Bind而不是Monad(即Applicative),但我们已经在使用pure,所以我们已经Applicative。
purescript ×12
ffi ×2
date ×1
do-notation ×1
haskell ×1
javascript ×1
node.js ×1
random ×1
typeclass ×1
types ×1