どうでも良いけど、やっとHaskellのIOアクションそのものは参照等価であることが納得できた気がする。
IOアクションの評価を一番最後まで遅延させ、外部要因や時間的要因を一切排除することによって、IOアクションの値は不変となり、最後に一度だけ評価をするIOアクションの値は一意性を満たすために、参照等価であると言うことができるのだな。
で、一度のIOアクションの評価で複数の副作用を扱うためにモナドや遅延評価を用いているわけだ

遅延評価は必須じゃないですね do 構文を「評価」しても結果は IO アクションという「値」になるだけで、それを「実行」するのはソースコードの外のランタイムがおこないます

@kakkun61 つまり私の認識に間違いがなければ、IOアクションは何度評価しても「IOアクションの実行」にはならないということでしょうか。

それと、差し支えなければお聞きしたいのですが「遅延評価を用いている」というのが明らかに誤った表現であったことは反省したいと思っているのですが、これは正確には「遅延評価のほうが参照等価なIOアクションの実装が容易である」と言いたかったのですが、これは間違いないでしょうか?(「人による」という回答になってしまうかもしれないことは承知の上でお聞きします)

(ggrksということであればスルーしても構いません)

「IOアクションは何度評価しても『IOアクションの実行』にはならない」
Yes、そうです!
putStrLn "hello" という式はあくまで「『"hello" を出力する』という手順が記されたデータ」で、何度評価しても「手順が記されたデータ」です
そのデータに main という特殊な名前を付けるとランタイムがその手順にしたがって実行してくれます
プログラムの意味としてはそんな感じになってます
後半については、正格評価で IO モナドの書き味は何も変わらないと思います
蛇足すると Haskell を調べてると「遅延 IO」というのが見つかると思いますが、これは Haskell が IO にモナドを採用する前の遺産なので気にしなくていいです

フォロー

@kakkun61 なるほど、よくわかりました。ありがとうございます!

ログインして会話に参加
Fedibird

様々な目的に使える、日本の汎用マストドンサーバーです。安定した利用環境と、多数の独自機能を提供しています。