-
Notifications
You must be signed in to change notification settings - Fork 471
Add json decoder examples #7133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
tests/tests/src/json_decoders.mjs
Outdated
| let match = json.id; | ||
| if (match === undefined) { | ||
| return; | ||
| } | ||
| if (match === null) { | ||
| return; | ||
| } | ||
| if (typeof match !== "string") { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the bottom case should be enough, as it covers the 2 cases on top as well.
tests/tests/src/json_decoders.mjs
Outdated
| let match$1 = json.name; | ||
| if (match$1 === undefined) { | ||
| return; | ||
| } | ||
| if (match$1 === null) { | ||
| return; | ||
| } | ||
| if (typeof match$1 !== "string") { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, bottom case is enough.
tests/tests/src/json_decoders.mjs
Outdated
| let match$2 = json.age; | ||
| if (match$2 === undefined) { | ||
| return; | ||
| } | ||
| if (match$2 === null) { | ||
| return; | ||
| } | ||
| if (typeof match$2 !== "number") { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And same here, bottom case is enough.
tests/tests/src/json_decoders.mjs
Outdated
| } | ||
| let email = json.email; | ||
| let tmp; | ||
| tmp = email !== undefined && !(email === null || typeof email !== "string") ? email : undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is similar to the above - typeof email !== "string" ? undefined : email or even typeof email === "string" ? email : undefined would be ideal.
tests/tests/src/json_decoders.mjs
Outdated
| return; | ||
| } | ||
| let match$2 = json.users; | ||
| if (match$2 !== undefined && !(match$2 === null || !Array.isArray(match$2))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here - Array.isArray(match$2) would cover these.
|
Let's cut down and use the latest compiler: type group = {
id: string,
name: string,
}
let decodeGroup = group => {
switch group {
| (dict{"id": JSON.String(id), "name": String(name)}) =>
Some({
id,
name,
})
| _ => None
}
}gives: function decodeGroup(group) {
let match = group.id;
if (match === undefined) {
return;
}
if (match === null) {
return;
}
if (typeof match !== "string") {
return;
}
let match$1 = group.name;
if (match$1 !== undefined && !(match$1 === null || typeof match$1 !== "string")) {
return {
id: match,
name: match$1
};
}
} |
|
Looks like this is not about untagged variants: The same example with tagged variants has the same shape:
|
|
One might need special, different algorithms to compile untagged variants pattern matching differently. |
First step: remove the distinction between cases with and without payload in the toplevel algorithm. On this test: ```res @unboxed type rec t = | Boolean(bool) | @as(null) Null | String(string) | Number(float) | Object(Dict.t<t>) | Array(array<t>) type group = { id: string, name: string, } let decodeGroup = group => { switch group { | (dict{"id": String(id), "name": String(name)}) => (id, name) | _ => ("e", "f") } } ``` Before: ```js function decodeGroup(group) { let match = group.id; if (match === undefined) { return [ "e", "f" ]; } if (match === null) { return [ "e", "f" ]; } if (typeof match !== "string") { return [ "e", "f" ]; } let match$1 = group.name; if (match$1 !== undefined && !(match$1 === null || typeof match$1 !== "string")) { return [ match, match$1 ]; } else { return [ "e", "f" ]; } } ``` After: ``` function decodeGroup(group) { let match = group.id; if (match === undefined) { return [ "e", "f" ]; } if (typeof match !== "string") { return [ "e", "f" ]; } let match$1 = group.name; if (match$1 !== undefined && typeof match$1 === "string") { return [ match, match$1 ]; } else { return [ "e", "f" ]; } } ``` The 3 cases have become 2: check for optional fields and check for which case it is.
94904b4 to
59b2ed7
Compare
More examples for when unboxed variant pattern matching code isn't as efficient as it could be.