1
0
テーマ、知りたいこと
Haskellはよく参照透過であるとか、副作用を持たないといわれています。しかし、標準入力系の関数(getLine等)は副作用があるとまではいかなくても、参照透過ではないんじゃないでしょうか?
どのような立場の意見でも歓迎です。おそらく唯一解はないので、皆さんがどう考えるのかを知りたいです。IOモナド以外はまだ勉強していないので、IOモナドに限った議論をして頂けるとありがたいです。
背景、状況
少し前からHaskellを勉強し始めた大学生です。今までは主に手続き型言語(C++, Javaなど)を勉強してきて、関数型言語を勉強するのは初めてです。プログラミング中級者くらいだと思います。
テーマは上記の通り、Haskellは参照透過なのか、Haskellに副作用はあるのか、です。よりテーマを限定するとすれば、getLine関数が参照透過であることの説明は何なのかを知りたいです。
個人的に調べた範囲では、IO系の処理はIOモナドが担っており、例えば"Hello world!"を出力するときは、関数が出力するわけではなくて、「"Hello world!"を出力するという命令」を関数が返している、といった説明を見かけました。しかしこれは出力に限った話で、入力のことには何も触れていません。
同じ考え方をすれば、getLine関数は「文字列を読み込むという命令」を返していることになります。しかし、モナドは値を格納しているそうなので(これも別のサイトで読みました)、例えば以下のコードでは、一行目のgetLineと二行目のgetLineの返り値は異なる値を格納している可能性がある、ということになります。これは、参照透過性を持たないということにならないでしょうか?
haskell
1main = do 2 str1 <- getLine 3 str2 <- getLine 4 print str1 5 print str2
あるいは、Haskellは参照透過だが、参照透過性を持たない関数を使うための機能がモナドなのでしょうか? とあるサイトでは、GHC.Base.unIO関数を使うことで、IOモナド内にある隠された関数を取り出すことができると説明されていました。もしモナドが参照透過性のない関数をラッピングして、Haskellには参照透過であるように見せているのだとしたら、ある程度納得できます。
個人的に調べた範囲でも意見が割れていたので、どのような意見でも歓迎です。そもそも関数型言語と手続き型言語では「副作用」という言葉の意味が違うという意見も目にしたので、これに関して説明してくださるとなおありがたいです。
あと、今回初めてteratailを使うのですが、参考にしたサイトURLは貼ったほうがよいのでしょうか?(他人の物を盗んでいるような気分になって途中でやめたのですが...)
回答7件
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。