I have an algebraic sum-of-products type in PureScript:
data IO
= Menu (Word8 -> Effect IO)
| LongMessage (Array String) (Effect IO)
| ShortMessage String (Effect IO)
| End
initialize :: Effect IO
I'd like to call initialize
from JavaScript, and then consume its result. If I run Main.initialize()
from JavaScript, I get a JS Object
that prints like the following to console:
LongMessage3 {value0: Array(15), value1: ƒ}
value0: (1) ['foo']
value1: ƒ __do()
[[Prototype]]: Object
What would the JavaScript code look like that recognizes this object as a value corresponding to the LongMessage
constructor?
First, to answer questions like this, you can just look at the compiled JS code yourself. It's located in ./output/My.Module.Name/index.js
. Just open it and take a look.
The current version of PureScript (0.15.2 as of this writing) compiles ADTs to a set of JS objects with unique prototypes.
I'm going to use a smaller example, because yours is a bit too large to be legible. Let's say my ADT looks like this:
data X = Y Int | Z String Boolean
a = Y 42
b = Z "foo" false
This would yield roughly the following JS (I say "roughly" because it's a bit more elaborate, but the essence is the same):
function Y(value0) {
this.value0 = value0
}
function Z(value0, value1) {
this.value0 = value0
this.value1 = value1
}
var a = new Y(42)
var b = new Z("foo", false)
When constructed like this, values of the type can be tested for the particular constructor by checking the prototype via instanceof
. So, for example, the following:
c = case a of
Y _ -> "It's a Y"
Z s _ -> "It's a Z with " <> s
would translate roughly to:
var c = (() => {
if (a instanceof Y) {
return "It's a Y"
}
if (a instanceof Z) {
return "It's a Z with " + a.value0
}
throw new Error("Invalid pattern match")
})()
A footnote: in your example the constructor seems to be named LogMessage3
instead of LogMessage
. This tells me that you're probably executing a bundle. During bundling functions may get renamed to avoid naming conflicts - that's where the "3" comes from.