Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How turn a PureScript ADT into JS String 'enum' for FFI

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.

like image 992
toastal Avatar asked Oct 19 '25 02:10

toastal


1 Answers

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.

like image 160
gb. Avatar answered Oct 22 '25 04:10

gb.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!