ReScriptでDOMを扱う

# 作るもの
ReScriptでDOMを扱います。
サンプルとして、以下を作成します。
<p class="codepen" data-height="300" data-slug-hash="jOoVObZ" data-pen-title="漱石先生クイズ" data-user="sgigagaeru" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sgigagaeru/pen/jOoVObZ">
  漱石先生クイズ</a> by sgigagaeru (<a href="https://codepen.io/sgigagaeru">@sgigagaeru</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# EventListenerの登録
まずはEventListerを登録して、以下のような動きをするところまで作ります。
<p class="codepen" data-height="300" data-slug-hash="WNBoKZM" data-pen-title="漱石先生クイズ#2" data-user="sgigagaeru" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sgigagaeru/pen/WNBoKZM">
  漱石先生クイズ#2</a> by sgigagaeru (<a href="https://codepen.io/sgigagaeru">@sgigagaeru</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

***
Global JS Valueである`document`と`window`をバインドします。[^1]
Global Valueなので`@val`が付きます。
まずは型にこだわらず多層型の`` `a ``でバインドします。
```ReScript:souseki_form.res
@val external doc: 'a = "document"
@val external win: 'a = "window"
doc["getElementById"]("btn")["addEventListener"]("click", () => {
     win["alert"]("吾輩は猫である。名前はまだ無い。")
   }, false);
```
[これで動きます。](https://rescript-lang.org/try?version=v11.1.0&code=AINwhgNgBApgHgFxgJwHaSgEwPYGMBcUA5GFALxQBEOuArgLYyoKUBQoG8SaGA7gJapCJclQGocvNjQDalAOYwEAUQgxGzAEIBPAJKZKAXQAUlAEYJUlAJRywmTMpBMEAGX4BnJKhRHTuCH5cAGtKABooY2tyAD4oAG9WKGTk8Ts1ZBYTSkA+FUBKeMB7BkBqZ0BzBkAhBkBohkAgBkBYFUBZJQLAPwZAAwZAQkdAEQYqmyTkgF8IgDNIDxhrAG5WIA)
***
これでは型付き言語の良さが全く活きないではないかということで、
```ReScript:souseki_form.res
@val external document: Dom.document = "document"
@val external windows: Dom.window = "window"
```
としたいところです。
しかしすでに`document`は`Dom.document`型に、`window`は`Dom.window`型にバインドされているので[^2][^3]、そのまま使います。
```ReScript:souseki_form.res
docment["getElementById"]("btn")["addEventListener"]("click", () => {
     window["alert"]("吾輩は猫である。名前はまだ無い。")
   }, false);
```
[これはエラーになります。](https://rescript-lang.org/try?version=v11.1.0&code=CYewxgrgtgpgdgFwNoCIDmMEFEA2NaIBCAngJLAoC6AFCgEYJwoCUqAhsMFgG7wIAyASwDOCeDABOVWmByCwAaxQAaAATVmqgLwA+VQG8AUKpMmA7oLigz7PBITSUgPhVAlPGB7BkDUzoHMGQEIMgaIZAIAZAWBVAWSU3QD8GQAMGQEJHQBEGAJZjEwBfNQAzNhxhGGYAbkMgA)
## Object Methodの登録
`getElementById`、`addEventLister`、`alert`をバインドします。[^4]
Object Methodなので`@send`が付きます。
```ReScript:souseki_form.res
@send external getElementById: (Dom.document, string) => Dom.element = "getElementById"
@send external addEventListener: (Dom.element, string, () => unit, bool) => unit = "addEventListener"
@send external alert: (Dom.window, string) => unit = "alert"
```
登録したObject Methodを用いて書くと、こうなります。
```ReScript:souseki_form.res
@send external getElementById: (Dom.document, string) => Dom.element = "getElementById"
@send external addEventListener: (Dom.element, string, () => unit, bool) => unit = "addEventListener"
@send external alert: (Dom.window, string) => unit = "alert"

addEventListener(getElementById(document, "btn"), "click", () => {
     alert(window, "吾輩は猫である。名前はまだ無い。")
   }, false);
```
[これで動く](https://rescript-lang.org/try?version=v11.1.0&code=AIZwpgdgJgBGAeAXMAnCBDANjA5mRAopmALaSIBCAngJJQBcMAFACID2JAdFGwMYCuZCIgA0MEIhQBLCDgCUMALwA+GOy5hiQxEpgAiPIS3lqdPQChQkWAmRosMdFCgEAbuQAyUiZFSNWHJyapORiEtKyYkwKKjD8EFKiMABGbGyYMarxibp6Ti7uwl4+EKgWVtBwSKgY2FioiP7qnADuMjwtYZIy8kpZCTqK+vUoiBbm+W6e3silKEyGRCHCplBMPALaYnrJiBB6ctu8mFK8ANZ6UZkwAN7mMA8PI4hMbdBsnfqAfCqAlPGA9gyAamdAOYMgCEGQDRDIAgBkAsCqAWSU-oA-BkABgyAQkdACIMEIO9weAF8xAAzLDgOQAbnMQA)ので問題ないですが、Pipe[^5]を使って
```ReScript:souseki_form.res
@send external getElementById: (Dom.document, string) => Dom.element = "getElementById"
@send external addEventListener: (Dom.element, string, () => unit, bool) => unit = "addEventListener"
@send external alert: (Dom.window, string) => unit = "alert"

document->getElementById("btn")->addEventListener("click", () => {
  window->alert("吾輩は猫である。名前はまだ無い。")
  }, false);
```
としておきます。[これも動きます。](https://rescript-lang.org/try?version=v11.1.0&code=AIZwpgdgJgBGAeAXMAnCBDANjA5mRAopmALaSIBCAngJJQBcMAFACID2JAdFGwMYCuZCIgA0MEIhQBLCDgCUMALwA+GOy5hiQxEpgAiPIS3lqdPQChQkWAmRosMdFCgEAbuQAyUiZFSNWHJyapORiEtKyYkwKKjD8EFKiMABGbGyYMarxibp6Ti7uwl4+EKgWVtBwSKgY2FioiP7qnADuMjwtYZIy8kpZCTqK+vUoiBbmPALaALTKhkQhwqZQTHrJiBB6crP5bp7eyKUoq7yYUrwA1npRmTAA3uYwMG3QbC07xKOrgHwqgJTxgPYMgGpnQDmDIAhBkA0QyAIAZALAqgFklf6APwZAAYMgEJHQAiDJCto8YABfMQAMyw4DkAG5zEA)
# Form情報の取得
`getElementsByName`を用いて`input`の情報をとっていきます。
```ReScript:souseki_form.res
@send external getElementsByName: (Dom.document, string) => Dom.nodeList = "getElementsByName"
@send external item: (Dom.nodeList, int) => Dom.element = "item"
@get external getValue: Dom.element => string = "value"
```
`getValue`はオブジェクトのプロパティ`value`の値を取得しているので`@get`を付けます。[^6]
```ReScript:souseki_form.res
document->getElementById("btn")->addEventListener("click", () => {
  window->alert(document->getElementsByName("Q1")->item(0)->getValue)
  }, false)
```
`alert`で表示させる表示を変えました。[これも動きます。](https://rescript-lang.org/try?version=v11.1.0&code=AIZwpgdgJgBGAeAXMAnCBDANjA5mRAopmALaSIBCAngJJQBcMAFACID2JAdFGwMYCuZCIgA0MEIhQBLCDgCUMALwA+GOy5hiQxEpgAiPIS3lqdPQChQkWAmRosMdFCgEAbuQAyUiZFSNWHJyapORiEtKyYkwKKjD8EFKiMABGbGyYMarxibp6Ti7uwl4+EKgWVtBwSKgY2FioiP7qnADuMjwtYZIy8kpZCTqK+vUoiOXglbY1DoZEIcIg1ABy6GRNgTwC2l0RvbHNEGxQYMWD+rPGC8urYOPWVXa1MImk61yHx6diMoiZaoHBbS5F4kcqGB7TbCGABqWH4YEYzUB5D64m6slyrjht3M5k2gnIAFplBd5pRaFAmHpkogIHo5MT8m5PN5kKUUFTeJgpLwANZ6KJ-ADe5hgMDa0DYLUZxFGTHx2mJpO0iyoKzIVIAigBGenEkFMAAMDJJ+FhmHhclFMAAvmIAGZYcBWoA)
***
`getElementsByName`は`Dom.nodeList`を返します。`Dom.nodeList`は配列でもリストでもないので、これをリスト化する`getlistedNodeList`を定義しました。
その際に`getLength`をバインドしています。
```ReScript:souseki_form.res
@get external getLength: Dom.nodeList => int = "length"
```
***
正解の選択肢には`data-correct-choice="true"`を設定しています。
この属性が設定された`input`タグの`value`を取得する`getCorrectAnswer`を定義します。
`data-*`属性を取得するのは`dataset`で`domStringMap`を返します。その`domStringMap`の`correctChoice`属性に`data-correct-choice`の値が入っています。[^7]
バインドします。
```ReScript:souseki_form.res
@get external getDataset: Dom.element => Dom.domStringMap = "dataset"
@get external getCorrectChoice: Dom.domStringMap => string = "correctChoice"
```
***
選択肢が選ばれているかは、`checked`を調べれば分かります。
```ReScript:souseki_form.res
@get external getChecked: Dom.element => bool = "checked"
```
これを用いて`getSelectedAnswer`を定義しました。
***
[だいたい動くバージョン](https://rescript-lang.org/try?version=v11.1.0&code=AIZwpgdgJgBGAeAXMAnCBDANjA5mRAopmALaSIBCAngJJQBcMAFACID2JAdFGwMYCuZCIgA0MEIhQBLCDgCUMALwA+GOy5hiQxEpgAiPIS3lqdPQChQkWAmRosMdFCgEAbuQAyUiZFSNWHJyapORiEtKyYkwKKjD8EFKiMABGbGyYMarxibp6Ti7uwl4+EKgWVtBwSKgY2FioiP7qnADuMjwtYZIy8kpZCTqK+vUoiOXglbY1DoZEIcIg1ABy6GRNgTwC2l0RvbHNEGxQYMWD+rPGC8urYOPWVXa1MImk61yHx6diMoiZaoHBbS5F4kcqGB7TbCGABqWH4YEYzUB5D64m6slyrjht0s4Km9ih+A8kBwiAAFojAh8Tt5BqofrliLJyWD8BCCbh8Cx0Ih0OBGv8NJc6YLuBwAMronAAWXQAAdclAeXz8KydPinoYAMJsFAoMC8RBaslsKS8BGingkSW7WUK2LhHq5Xi6-WG42m81q9ma-DGg0AazADFFyOEqNS6WdZMDwYs5gA9AmYIA7t0AIW70QC0UYB5VUAFwmAOwYZHL+Ih80sjmBAEkMACUwOLeNI5aXMLTANYMgB4LQCwvoBNBkA0QyJ5OGU7B8ufWkwSnvCunGAAWlUSOFMBbEnMxB0Q9pI+n46G1JnsQA3uYYMu2UzSWTdPvafOhyTyeYTzAk6mMzAbxJ5yCmAAGOSANIMgCRDJ+iDfsgJBMFIciAH4MgDmDPmi7zIgNZ1g2UhNvmK6IB2Pb9qer6YGkCqMAy86hku2HPuuMBusuxG6FIfTPqeUgAGbPDAAA8MC-jAh7YYeAC+QksXAmDgPxgmgeBpBQXIYicEpRFsHKUFzjAACMcgiU+p4qWpF7khp2nmKJA5vowgDG1oAx5H5oAHgmAHlGgBFAfmWKYPClaACvx3YWdqroGogACCEAgC0qAThRyHLuO5GOrIa5snR-l6oFIVhRFQwSSKYWJLwV7Zfx5gAD4xRIwmonoFilYJbFSCgEiKUp+oSEJzGsRxdUNWByiGNyvL8nefoBe6JpmmAShDHokjwno-FdV+vX4LCHlgKJp6aJJh4pW6wWheFKBMC1vyieZr7powTmAKoMgAxDIA+gxOa57meT5fn4OKwSGsG6UHZFSFAthc6qPFOCJToyXvZ9yBQD9mXLhIqK5Yg+Xwzox41bSFWxFVJVlYgh4LUkSmcMdbUqM+7GckaMa8EGUBMITCgE-Vi0wti63iVthgfcQX0w-tqBHWAEg6WZT40WwEAUIgEBai2tO6NEqLHvp55blAo40gjQybII5BDUYyGLFQKxkEwegAIqaXocgG8OGs7quqs6C6qWGrDKC6Nh25jqzw1u3tGUoNRbLgLz0Me176ua6cBs84F30C8HzswAAVvwUB4ECQyu7tkeKEMYcJ-zQcwAA-Potlwd2gCA-3NjB6IAsHJV92gBADBYKdkCAIDoHguS2YA9gxzQA1MPMC52lScwKP+it4AQgyAFYMd35oAe2qACreQ-T2PRd85HM96HBgDqDHd7fPm00BsC084jIgTDp5n0X7wAOhAI9j13Pd4HIYvmLr2gG3MbQph6Z6GSDLG219nBuE8FuUoh09C8HlgGPQYhJbS1lkgsQbEsDgG-kAA)ができました。
# DOM情報の書き換え
あとは`innerHTML`を書き換えて、ページを書き換えます。
innerHTMLへのアクセスにはsetter[^4]を用います。
```ReScript:souseki_form.res
@get external getBody: Dom.document => Dom.element = "body"
@set external setInnerHTML: (Dom.element, string) => unit = "innerHTML"
```
[一旦の完成版です。](https://rescript-lang.org/try?version=v11.1.0&code=AIZwpgdgJgBGAeAXMAnCBDANjA5mRAopmALaSIBCAngJJQBcMAFACID2JAdFGwMYCuZCIgA0MEIhQBLCDgCUMALwA+GOy5hiQxEpgAiPIS3lqdPQChQkWAmRosMdFCgEAbuQAyUiZFSNWHJyapORiEtKyYkwKKjD8EFKiMABGbGyYMarxibp6Ti7uwl4+EKgWVtBwSKgY2FioiP7qnADuMjwtYZIy8kpZCTqK+vUoiOXglbY1DoZEIcIg1ABy6GRNgTwC2l0RvbHNEGxQYMWD+rPGC8urYOPWVXa1MImk61yHx6diMoiZaoHBbS5F4kcqGB7TbCGABqWH4YEYzUB5D64m6slyrjht0s4Km9ih+A8kBwiAAFojAh8Tt5BqofrliLJyWD8BCCbh8Cx0Ih0OBGv8NJc6YLuBwAMronAAWXQAAdclAeXz8KydPinoYAMJsFAoMC8RBaslsKS8BGingkSW7WUK2LhHq5Xi6-WG42m81q9ma-DGg0AazADFFyOEqNS6WdZMDwe9Gpm+AoRyolK4m0EKP2AOFuVSUCod3V1Q5-JoEFKKAAEgAVaUeN5BYU7Hp-bJnPQySu1+sWcwAen7MEAd26AELd6IBaKMA8qqAC4TAHYMMjl-EQc6WRzAgCSGABKYHFvGkcpXmFpgGsGQA8FoBYX0AmgyAaIYB0PDKdg2vPrSYGnONTTjAALSqJG5seEjmMQOiPrSz7rt+Qxfm+sQAN7mDAMCgShJLkrosESH+j7oWS5hITAg4juOMBYYgf4gkwAAMciANIMgCRDORlHICQTBSHIgB+DIA5gxzgB8yINuu77lIh5zkBiDnted7IcRmBpAqjAMn+oaAbShGoW6KEKboUh9IRyFSAAZs8MAADwwNRMDwRJ8EAL52QZcCYOA1m2cxyhURxYicL58lsHK7G-jAACMcgOQRyH+YFTKkmSwVheYjn3iRjCAMbWgDHkXOgAeCYAeUaAEUBc5Ypg8IboAK-FXil2qugaiAAIIQCALSoO+qkCShb4qY6sggWyWnVXqtUNU1LVDC5IpNYkvDxeN1nmAAPh1Ej2aiegWIttlGVIKASD5vn6hIdn6YZJlbTtFHKIY3K8vyOF+jV7ommaYBKEMeiSPCejWWd2GXfgsIlWAjnIZornwQNbr1Y1zUoEwB2-I5yXEWOjB5YAqgyADEMgD6DHlhXFaVFVVfg4rBIawbDTDrX8UCEm-qo3U4L1Oj9cTpPIFAFOjShEiopNiDTdzOiIRttIrbEa0LUtiDwT9SS+Zw8NHSohHGZyRoxrwQZQEwssKDL22-TC2LA85YOGCTxBkxz0OoHDYASOFSUEahbAQBQiAQFqx6a7o0SoohUVshJkGvjzQwZtod1GAJixUCsZBMHoACKIV6HIUdPlAL40sBgc6C6g2GpzKC6MHWdQbSUc6oXUMjSgGlsuAlvs8XpcQeXocXebbPkzb9d5zAABW-BQHgQJDAXkOt4oQxN7Vvd1zAAD8+iZdxV6AID-X2MHogCwcmvV6AEAMFgD2QIAgOgeC5JlgD2DF9ADU98wJPQ19zAj-6IfgBCDIAVgxY3OgA9tUACred935PznlbVuH89DcUAOoMWNj6EQjuQKOyYCx-jLBWVAPYPBMGHqPdq0CzLJBQMoB+T8z4XzwHIJ25hkHCCjnMbQphtZ6GSB7NOf58huE8BBSsideDewDHoMQrt3aeyEWIIyWBwA0KAA)
# `module`を使った方が良いのかも
いまバインドのところは
```ReScript:souseki_form.res
@send external getElementById: (Dom.document, string) => Dom.element = "getElementById"
@send external addEventListener: (Dom.element, string, () => unit, bool) => unit = "addEventListener"
@send external alert: (Dom.window, string) => unit = "alert"
@send external getElementsByName: (Dom.document, string) => Dom.nodeList = "getElementsByName"
@send external item: (Dom.nodeList, int) => Dom.element = "item"
@get external getValue: Dom.element => string = "value"
@get external getLength: Dom.nodeList => int = "length"
@get external getDataset: Dom.element => Dom.domStringMap = "dataset"
@get external getCorrectChoice: Dom.domStringMap => string = "correctChoice"
@get external getChecked: Dom.element => bool = "checked"
@get external getBody: Dom.document => Dom.element = "body"
@set external setInnerHTML: (Dom.element, string) => unit = "innerHTML"
```
となっています。さすがにこれは、見通しが良くないので、
```ReScript:souseki_form.res
module Document = {
  @send external getElementById: (Dom.document, string) => Dom.element = "getElementById"
  @send external getElementsByName: (Dom.document, string) => Dom.nodeList = "getElementsByName"
  @get external getBody: Dom.document => Dom.element = "body"
}
module Element = {
  @send external addEventListener: (Dom.element, string, () => unit, bool) => unit = "addEventListener"
  @get external getDataset: Dom.element => Dom.domStringMap = "dataset"
  @get external getValue: Dom.element => string = "value"
  @get external getChecked: Dom.element => bool = "checked"
  @set external setInnerHTML: (Dom.element, string) => unit = "innerHTML"
}
module NodeList = {
  @get external getLength: Dom.nodeList => int = "length"
  @send external item: (Dom.nodeList, int) => Dom.element = "item"
}
module DomStringMap = {
  @get external getCorrectChoice: Dom.domStringMap => string = "correctChoice"
}
```
と、`module`で分けるのかなと思いました。
その他、関数をまとめたりする変更を加えて、[完成版](https://rescript-lang.org/try?version=v11.1.0&code=LYewJgrgNgpgBAERAYwsGA7ALnAvHAbwCg44ABAZ0zDhgA8sYAnDAQyjgHMYsBRWdNgBCATwCSYAFxwAFEmAA6MCjSYsAGjgUsTAJYZOASjwA+RCEUwBavHABE3PteHiwdkuSoYa9Ri3ZcPPwwglgUogByrOjSchZKKqGa2noGxrhm8goY4DAAMrratg5BzmGR0TDupGSOtAzMbByOQuAi0lnKqKGm5pZlxQBGbe4AvkSgkLBwwT34xDVePg3+HKxgYLwAbmoF2pjMsVlWIWrJOvqcmjLpZhAYuhpwwyBQt3D3j8XrmzvYe4wMMxquQ6r5GgFHAhWFhWFQsB14ic5pl4spgABlC4GACyrAADsUwDC4TwQbUePU-E1AlgAGrsCAwRH9U7YXopS7FLaMqoeCk4cGrWkAYQAFjBkABrGBSPoKZE2DLPECvYrICXS2Xk+FUiEceFiDBApgACQAKji8kckWVzqkjL1Pjh8HZ9CaLVaxhNwNB4BFcgDbAtQZShTTHHlMJwsGKWdlA4UXWZ9C77LADLGddQ9cLHiEbYocmB8knNKn3scBq788BvZM-X0sQ68YT5vywSsIzwRSAmExJVhxSBdMhmfL0c3Lq2OdjOOq+wPkEOxSOx96iAB6TdwQB3boAQt0kgFoowDyqoALhMAdgz6fEQLAXgMlwBJDAAlGAY5B6fF3qBJwDWDIAeC0AWF9AE0GQBohi3HdIyTWUH1LIp42LOCcAAWlRVkeh-bQiFgHAoP2MBYKDfBEKIswQxwuAMxjMVbBIpNUMIpMFEjaNYyIDxtz3Q84Do7RUNrGQAAZDEAaQZAEiGXisH4xhgBkXRDEAPwZAHMGC8qzZLAXzfD9dC-C9MKwACQPA0hOKgVVCWkVM4FQ+VFXZfSPAopdKPM2xdFMDxSF0AAzOB3IAHjgQTCH0ghRnGUhSCsKgQqTAhJIYxNtAUAT5M0BQMrMkB8Tk6y4AARkMcL2NILKcqo2M8sKohxi3AAqOAACkKAUAEFG814wGfXRODFHBH0Af3lADEGQALBjgAcAEcIF0Ac4EAGQZAFH9QBAyKUwA1hkAS4ZADKGQA2hkAfO1ABkIubAECGQBkhkASwYhrgOrNwgrjLIeLBxMAac0jsAMwYoG0C8lsAAl9H0AZ+VxMAMAzf2839AEFbQB1BkAHvjAACGW6OqgLqer6uBYgAclYTQbLRwZrLMHHjGx1hKKTPG4Bx7DKWchGkd6tMZG8zQPqefRHneCgAHdHg1SiimIAAfEntDC3pWawIhBdC7yZu0dKMoHbRRl6byGZlp4ae6umGc0BWWYewxDBq9jOIPaRAHBjQAs7UAVQZABiGQB9BkADwTADyjQAigIvHkoCZR9ABX44DbscABBDBOeYVHZDUnobJeN4yYjmx9LJzkDEp3CeCDkOmFsGRmc0bz3g15GsBkDxVaYWXxpgbQAH0PaZd4fLgFXpbLrBjAIZu+JMWY1GYngGU9mAlei+ACF1mveVGdRHNljw7HcQ3btNuBAB2GQB+hkAZ4Y5sAeoZACuGQBhhi3227ZGwBZBgvQAzxUAMBdbpADAhCwDARR-aUw+dMnnRTuBb-vx-n6lLP3jkUpPpGCSU0xdFUNgVCSBug90cN3bA4QRBRHQDIOwABFfKdhDCoTwowAiYDHKUmQIuQc6cOah3wCAghJYAS4LTsHChTAZDwGVDAVCCCsC9ywNCWE8JoEWCnLiAk3Dez9kHMOUcrDXQ6CZNgohOAqCwGXLKchlChb4MYp3QOjDmAyE4aIzUMowCG1KpSAAVhAMA3A5hwBIeI5cajM64HwEowcqjdGZwAPz2EAMbWgBjyKUsBQAgP92DDnYQAsHIBKCYAIAYQQUXQBQCgrBuDFACYAewYwkAGosl2NIY4zxcAcn2BiYAIQZABWDHbC8gA9tUACremSim5LcSosATjGn2CUhDO2cSPAQNCAI2B2BuGtDACIDhZQFCGmNMwT0eQZCWOsepdpdh-KDCYCYbJuTEnJO4IbWqfS1ADMgVw+BZRRASDQYMB+2DxnqQUD8bYuxoImjQcgP+dhNDfwfk-UcUpc7sCoIbIAA)としました。
# ReScriptファイルはモジュールです
ReScriptでは一つのファイルは一つのモジュールとして扱われます。
そのため生成されるJSファイルには`export`(`esmodule`の場合)か`exports`(`commonjs`の場合)が書かれます。
ブラウザに読み込ませる場合は`esmodule`にする必要があり、モジュールとして扱われるので`script`タグで`type="module"`の設定が必要です。
そしてモジュールをローカルで読み込むとCORSエラーになるので、試験時はローカルのWebサーバ経由でアクセスする必要があります。

[^1]:https://rescript-lang.org/docs/manual/latest/bind-to-global-js-values
[^2]:https://rescript-lang.org/docs/manual/latest/api/core#value-document
[^3]:https://rescript-lang.org/docs/manual/latest/api/core#value-window
[^4]:https://rescript-lang.org/docs/manual/latest/bind-to-js-function#object-method
[^5]:https://rescript-lang.org/docs/manual/latest/pipe 
[^6]:https://rescript-lang.org/docs/manual/latest/bind-to-js-object#bind-using-special-getter-and-setter-attributes
[^7]:https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/dataset