1

Haskell の iteratee I/O とは何かを理解しようとしています。次の Haskell-Wiki をいくつかの定義で確認しました。

その関数の 2 行目、3 行目、および最後の 2 行の意味がわかりません。

enumerator :: FilePath -> Iteratee (Maybe Char) o -> IO o
enumerator file it = withFile file ReadMode
  $ \h -> fix (\rc it -> case it of
    Done o -> return o
    Next f -> do
      eof <- hIsEOF h
      case eof of
        False -> do
          c <- hGetChar h
          rc (f (Just c))
        True -> rc (f Nothing)
    ) it

iteratee 関数が何をするかは知っていますが、いくつかの行がわかりません。このウィキページの他の機能は本当に不思議です。いくつかの説明が抜けているので、彼らが何をしているのか理解できません。

4

2 に答える 2

4

あなたが言及した行は、列挙子/反復子固有ではありませんが、説明を試みることはできます。


withFile name mode = bracket (openFile name mode) (closeFile)

つまり、withFileファイルを開き、指定されたコールバックにハンドルを渡し、コールバックの完了後にファイルが確実に閉じられるようにします。


fix固定小数点コンビネータです。例えば、

fix (1 :) == 1 : 1 : 1 : 1 : ...

通常、自己再帰関数を記述するために使用されます。TFAE:

factorial 0 = 1
factorial n = n * factorial (n-1)

factorial n = fix (\f n -> case n of 0 -> 1; n -> n * f (n-1)) n

これらの構造なしで同じ関数を書き直すことができます。

enumerator :: FilePath -> Iteratee (Maybe Char) o -> IO o
enumerator file it = do
  h <- openFile file ReadMode
  let rc (Done o) = return o
      rc (Next f) = do
        eof <- hIsEof h
        case eof of
          False -> do
            c <- hGetChar h
            rc (f (Just c))
          True -> rc (f Nothing)
  o <- rc it
  closeFile h
  return o

withFileただし、例外を処理するため完全に正確ではありませんが、これはそうではありません。

それは役に立ちますか?

于 2012-07-13T01:07:14.627 に答える
2

おそらく、ラムダ関数に名前が付けられていれば役立つでしょう。

enumerator :: FilePath -> Iteratee (Maybe Char) o -> IO o
enumerator file it = withFile file ReadMode $ stepIteratee it
  where
    stepIteratee (Done o) _h = return o
    stepIteratee (Next f) h = do
      eof <- hIsEOF h
      case eof of
        False -> do
          c <- hGetChar h
          stepIteratee (f (Just c)) h
        True -> stepIteratee (f Nothing) h

stepIterateeiterateeが停止するまで、ファイルとiterateeの両方をステップスルーし続けます。

于 2012-07-13T06:56:21.123 に答える