-
Notifications
You must be signed in to change notification settings - Fork 7
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
Wrong flatMap definition? (without world version) #1
Comments
Thank you for your contribution. |
starをつけてらっしゃる方の中に韓国籍の方がいらっしゃるようでしたので慣れない英語で書きました。日本語での質問も記載しておきました。よろしくお願いします。 |
ちょっと調べてみました。 出版された書籍では bin/cat_without_world.js のファイルに定義されたflatMap関数を採用しています。
この定義は、tanagumoさんが最後に掲載したflatMap関数と実質的に同一のものになっていると思いますが、いかがでしょうか? ところで、このレポジトリには執筆の途中でボツになったコードがいくつかまぎれこんでいます。 追伸: |
間が空いてしまいまして申し訳ありません。 まずIOモナドについて自分の理解を述べさせて頂きたいのですが、IO[A]がもつ副作用はIO[A] => Aという風にIOモナドのコンテキストから中の値を取り出す際に発生するという認識です。 実際にghciで確認する限りでは自分の理解と同じ挙動をしていると思います。
ただ、このIOモナドの副作用の発生タイミングがhaskellに限定的な話なのかIOモナド一般に求められる性質なのかについて私には知見がありません。以下、自分の理解が正しい仮定の元で記載させて頂きます。 https://github.com/akimichi/functionaljs/blob/master/bin/cat_without_world.js で定義されているflatMapも以前に私が記載したflatMapも型レベルで見ると同じなのですが副作用の発生タイミングが異なります。bin/cat_without_world.jsの定義で上記のghciと同じ事をやってみますと
となります。ちなみにbin/cat_without_world.jsのIO.putCharの定義は
となっており、型レベルではChar => IO[Unit]ですが、putCharを適用した時点で画面表示されてしまうので以下が正しいのではないかと思います(実際別のファイルでは以下のような定義になっていた気がします)。
但し、putCharの定義を上記のように修正してもbin/cat_without_world.jsのflatMapの定義のままだとIOモナドから値を取り出す時点まで副作用の発生を遅延させる事はできません。 IOモナドの性質として、IOモナドから値を取り出す時点で副作用を発生させるべきなのであれば先日記載させて頂いた定義である必要があるかと思いますが如何でしょうか。 ちなみにですが、参照しているブランチはmasterです。 長文になってしまいましたがよろしくお願いします。 |
こちらでも同じような結果になることを確認しました。 |
https://github.com/akimichi/functionaljs/blob/master/bin/cat.js のIOの定義は期待すべきIOモナドの挙動になっていると思います。 実際
上記のコードはIOモナドの定義時ではなく、 worldを明示するバージョンとwithout_worldバージョンのflatMapですが worldを明示するバージョン
without_worldバージョン
となっています。worldを明示するバージョンは そこで、この箇所を 結果的にwithout_world版とworldを明示するバージョンの実質的な際はpairの有無だけかと思います。具体的にはwithout_world版のIOの定義は下記の様になるのではないでしょうか。 IOの定義(議論上必要な箇所のみ抜粋)
よろしくお願いします。 |
tanagumoさん、 さて問題は、不覚にも間違った内容を書籍に載せてしまった点です。 |
こちらこそご回答ありがとうございました。 |
You define
IO.flatMap
as below. (https://github.com/akimichi/functionaljs/blob/master/bin/io_without_world.js#L48-L53)But this definition evaluates
self.run(actionAB(self.run(instanceA))
eagerly.For example, the code below displays
hello monad
before executingIO.run(e)
.So I think the definition should be as below.
https://github.com/akimichi/functionaljs/blob/master/bin/io_without_world.js#L48-L53
にて、IO.flatMapは以下のように定義されています。
しかし、この定義では
self.run(actionAB(self.run(instanceA))
を正格評価してしまうと思います。(正格評価という表現が適切か分かりませんが、
IO.flatMap(instanceA)(actionAB)
の時点で評価されます。)例えば、以下のコードでは
IO.run(e)
の実行前にhello monad
が表示されます。そのため、flatMapの定義としては以下のほうが適切かと思いますが如何でしょうか。
よろしくお願いします。
The text was updated successfully, but these errors were encountered: