One way to do this would be to decode your JS code as JSON. I made a few assumptions from your snippet of JS (please correct me if I’m wrong)
- The JS data is an array of arrays. The inner arrays are always two elements, the first a string and the second the data type of that “fruit”
- All the second elements of the inner arrays are different
This example uses bs-json. You’ll need to understand that API first but will try to annotate what’s going on:
type fruit =
| Apple(array(int))
| Banana(string)
| Orange(array((string, int)));
/*
Json.Decode.tuple2 decodes a JSON array with two elements
Json.Decode.string decodes a string
Json.Decode.(array(int)) decodes an array of integers
*/
let decodeApple = Json.Decode.(tuple2(string, array(int)));
/*
From the example above you can guess what's going on with the next two
*/
let decodeBanana = Json.Decode.(tuple2(string, string));
let decodeOrange = Json.Decode.(tuple2(string, array(tuple2(string, int))));
/*
Json.Decode.oneOf will try each decoder and give you back the first
one that succeeds.
Json.Decode.map will map the result of the successful decode. We need
this to map it into the fruit type. Notice how we only care about the
second part of the tuple
*/
let decode =
Json.Decode.oneOf([
decodeApple |> Json.Decode.map(x => Apple(snd(x))),
decodeBanana |> Json.Decode.map(x => Banana(snd(x))),
decodeOrange |> Json.Decode.map(x => Orange(snd(x))),
]);
let json = {|
[
["Apple", [1, 10, 20]],
["Banana", "taste nice"],
["Orange", [
["sour", 5],
["sweet", 2]
]]
]
|};
let fruits = Json.parseOrRaise(json) |> Json.Decode.array(decode);
/*
fruits should be
[|
Apple([|1, 10, 20|]),
Banana("taste nice"),
Orange([|("sour", 5), ("sweet", 2)|]),
|]
*/