I'm looking at some documentation for JS and it's using a string as a makeshift 'enum'. It'd be better to represent this as an algebraic data type, ADT, in my application; however, I'm not really sure what is the best way to turn that ADT into a String
on an object for the foreign function interface, FFI, to consume. Given conceptually:
data Foo = Bar | Baz
type Qux = { foo :: Foo }
foreign import quux :: forall e. Qux -> Eff (console :: CONSOLE | e) Unit
main = do
quux { foo : Bar }
and where qux
is { foo : "bar" | "baz" }
exports.quux = function(qux) {
return function() {
console.log(qux)
//=> Object { foo : "bar" }
}
}
In Elm I'd use Json.Encode
in core
to transform the record into a JS object to pass it along, but I'm not sure of the analog in PureScript.
I would do something like this:
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 }
The idea being you adapt the arguments for the FFI function _quux
with quux
, and then avoid exporting _quux
from the module, so only the "safe" interface is accessible.
Another advantage of this approach is you could give the quux
function a more PS-friendly argument setup, as passing records as options is not generally the norm, unless the function is going to accept a lot of stuff:
quux :: forall e. Foo -> Eff (console :: CONSOLE | e) Unit
quux foo = _quux { foo: printFoo foo }
main = do
quux Bar
Basically what I'm suggesting is that whenever you're using the FFI you want to do as little work as possible in the FFI, and handle as much of the implementation as you can in PS. That way more of the code you write is still checkable by the compiler, and you don't have to do anything clever in the JS or write things that may break if PS's implementation details change in some future version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With