如何将 PureScript ADT 转换为 FFI 的 JS 字符串 'enum'
How turn a PureScript ADT into JS String 'enum' for FFI
我正在查看 JS 的一些文档,它使用字符串作为权宜之计 'enum'。在我的应用程序中最好将其表示为代数数据类型 ADT;但是,我不太确定将 ADT 转换为对象上的 String
以供外部函数接口 FFI 使用的最佳方法是什么。从概念上给出:
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 中,我会在 core
中使用 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 }
想法是将 FFI 函数 _quux
的参数调整为 quux
,然后避免从模块中导出 _quux
,因此只有 "safe" 接口可以访问。
这种方法的另一个优点是您可以为 quux
函数提供更多 PS-friendly 参数设置,因为将记录作为选项传递通常不是规范,除非该函数将接受一个很多东西:
quux :: forall e. Foo -> Eff (console :: CONSOLE | e) Unit
quux foo = _quux { foo: printFoo foo }
main = do
quux Bar
基本上我的建议是,无论何时使用 FFI,您都希望在 FFI 中做尽可能少的工作,并在 PS 中处理尽可能多的实现。这样,您编写的更多代码仍可由编译器检查,并且您不必在 JS 中做任何巧妙的事情,也不必编写如果 PS 的实现细节在未来某个版本中发生变化可能会破坏的东西。
我正在查看 JS 的一些文档,它使用字符串作为权宜之计 'enum'。在我的应用程序中最好将其表示为代数数据类型 ADT;但是,我不太确定将 ADT 转换为对象上的 String
以供外部函数接口 FFI 使用的最佳方法是什么。从概念上给出:
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 中,我会在 core
中使用 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 }
想法是将 FFI 函数 _quux
的参数调整为 quux
,然后避免从模块中导出 _quux
,因此只有 "safe" 接口可以访问。
这种方法的另一个优点是您可以为 quux
函数提供更多 PS-friendly 参数设置,因为将记录作为选项传递通常不是规范,除非该函数将接受一个很多东西:
quux :: forall e. Foo -> Eff (console :: CONSOLE | e) Unit
quux foo = _quux { foo: printFoo foo }
main = do
quux Bar
基本上我的建议是,无论何时使用 FFI,您都希望在 FFI 中做尽可能少的工作,并在 PS 中处理尽可能多的实现。这样,您编写的更多代码仍可由编译器检查,并且您不必在 JS 中做任何巧妙的事情,也不必编写如果 PS 的实现细节在未来某个版本中发生变化可能会破坏的东西。