javascript-如何将PureScript ADT转换为FFI的JS字符串“枚举”

我正在查看JS的一些文档,它使用字符串作为临时的“枚举”.在我的应用程序中最好将其表示为代数数据类型ADT.但是,我不确定如何将ADT转换为对象上供外部函数接口FFI使用的String的最佳方法.从概念上讲:

data Foo = Bar | Baz

type Qux = { foo :: Foo }

foreign import quux :: forall e. Qux -> Eff (console :: CONSOLE | e) Unit

main = do
  quux { foo : Bar }

qux是{foo:“ bar” | “巴兹”}

exports.quux = function(qux) {
  return function() { 
    console.log(qux)
    //=> Object { foo : "bar" }
  }
}

在Elm中,我会在核心中使用Json.Encode将记录转换为JS对象以将其传递,但​​是我不确定PureScript中的模拟.

解决方法:

我会做这样的事情:

data Foo = Bar | Baz

printFoo :: Foo -> String
printFoo = case _ of
  Bar -> "bar"
  Baz -> "baz"

type Qux = { foo :: Foo }

foreign import _quux :: forall e. { foo :: String } -> Eff (console :: CONSOLE | e) Unit

quux :: forall e. Qux -> Eff (console :: CONSOLE | e) Unit
quux args = _quux { foo: printFoo args.foo }

main = do
  quux { foo : Bar }

您的想法是使用quux修改FFI函数_quux的参数,然后避免从模块中导出_quux,因此只能访问“安全”接口.

这种方法的另一个优点是,您可以为quux函数提供一个更加PS友好的参数设置,因为将记录作为选项传递通常不是常态,除非该函数将接受很多东西:

quux :: forall e. Foo -> Eff (console :: CONSOLE | e) Unit
quux foo = _quux { foo: printFoo foo }

main = do
  quux Bar

基本上,我的建议是,无论何时使用FFI,您都希望在FFI中做尽可能少的工作,并在PS中处理尽可能多的实现.这样,您编写的更多代码仍可以由编译器检查,并且您不必在JS中做任何聪明的事情,也不必编写可能会在PS的实现详细信息在将来的版本中更改的情况下中断的事情.

上一篇:在Enum(EntryPointNotFound)上使用IntPtr从C#调用Rust失败


下一篇:python-CFFI:TypeError:ctype’char []’的初始化程序必须是字节或列表或元组,而不是str