如何将PureScript ADT转换为JSI的JS String'enum'

时间:2017-01-27 04:34:42

标签: javascript adt ffi purescript

我正在查看JS的一些文档,它使用字符串作为临时'enum'。在我的应用程序中,最好将其表示为代数数据类型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" | "baz" }

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

在Elm中我会在Json.Encode中使用core将记录转换为JS对象以传递它,但我不确定PureScript中的模拟。

1 个答案:

答案 0 :(得分:3)

我会做这样的事情:

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,因此只有" safe"界面可以访问。

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

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

main = do
  quux Bar

基本上我所建议的是,无论何时使用FFI,您都希望尽可能少地在FFI中完成工作,并尽可能多地处理PS中的实施。这样,编写的代码仍然可以检查更多的代码,如果PS的实现细节在未来的某个版本中发生变化,那么您不必在JS中做任何聪明的事情或编写可能会破坏的内容。