将 javascript 对象发送到纯脚本函数

Sending a javascript object to a purescript function

我正在像这样集成 javascript 和 PureScript:

  //App.js
  const Calculator = require('../purescript/output/Main/index')

  const config = {
    grossIncome: 128183912,
    married: true
  }

  const result = Calculator.run(config)

但我不确定如何编写 PureScript 部分来接收 javascript 对象。我们可以假设所有输入都是有效的。

PureScript 中相应的类型定义如下所示:

type CalculatorConfig = {
    grossIncome :: Int,    -- or should it be Number?
    married :: Boolean
}

函数 run 看起来像这样:

run :: CalculatorConfig -> String
run cfg = if cfg.married then "Married" else "Bachelor"

(假设您的结果类型是 String;请在此处替换您的实际类型)


但是,这仅适用于 函数 - 即不产生任何副作用的函数,例如 input/output、显示 UI、发射导弹等。如果你的函数 需要有副作用,那么它的 return 类型应该是 Effect String 而不是 String:

run :: CalculatorConfig -> Effect String
run cfg = do
   log "Running calculator!"
   if cfg.married then pure "Married" else pure "Bachelor"

在这种情况下,您必须像这样从 JavaScript 调用它:

const result = Calculator.run(config)()

看到最后多余的括号了吗?这就是 Effect 被编译为 JavaScript 的方式——作为一个函数。这意味着 run return 不是 String,而是 程序 (又名函数),一旦执行,将产生String.


如果你真的想让 JavaScript 不知道任何额外的东西,你可以将你的 run 函数导出为 EffectFn1,这是一个特殊的包装器,允许将 PureScript 风格的有效函数表示为 JavaScript 风格的函数:

runImpl :: CalculatorConfig -> Effect String
runImpl cfg = do
   log "Running calculator!"
   if cfg.married then pure "Married" else pure "Bachelor"

run :: EffectFn1 CalculatorConfig String
run = mkEffectFn1 runImpl

或相同的更短的方式,没有 runImpl 的单独定义:

run :: EffectFn1 CalculatorConfig String
run = mkEffectFn1 \cfg -> do
   log "Running calculator!"
   if cfg.married then pure "Married" else pure "Bachelor"