我正在查看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中的模拟。
答案 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中做任何聪明的事情或编写可能会破坏的内容。