8

私は haskell IO を理解しようとしていますが、stdin のこの機能は最終的に私を混乱させます: たとえば、getContents のような関数を使用しようとすると:

let main = do x<-getContents; putStrLn x

次のエラーが表示されます。

hGetContents: illegal operation (handle is closed)

これでIOを行うにはどうすればよいですか?修正はありますか、それとも別のアナログ IO 関数を探す必要がありますか?

4

3 に答える 3

9

getContents == hGetContents stdin. 実際hGetContents、そのハンドルは (半) 閉じていることを示しており、これは stdin から再度読み取ろうとすると失敗することを意味します。

Haskell User GuideAfter using getContentsを見てください。

于 2013-08-10T10:12:45.070 に答える
6

別のアプローチも調査することをお勧めします。getContentsおよび同様の操作にはいくつかの固有の問題があります。

  1. 無効なハンドル (既に閉じられているハンドル) を持つことができます。これはほとんどの言語で一般的ですが、もっとうまくやることができます。理想的には、ハンドルを閉じたら、それ以上使用できないようにしたいと考えています。
  2. getContentslazyIOであり、(他の問題の中でも) 次のことを意味します。
    • ハンドルがいつ閉じられるかをほとんど、またはまったく制御できません。
    • によって返された文字列を処理している間getContents、データは遅延IO操作を使用して読み取られます。これは、純粋な計算内でIO効果とエラーが発生する可能性があることを意味します。

より安全な代替手段は、反復、コンジット、またはパイプと呼ばれる別の概念を使用することです。アイデアは、コンポーネントを、入力データを読み取ったり、出力を書き込んだりして、それらを結合するものとして記述することです。これにより、非常に堅牢で洗練されたコードを書くことができます。

于 2013-08-11T12:24:30.270 に答える