理解Haskell中的iteratee-functions

时间:2012-07-12 22:51:20

标签: haskell enumerator iterate

我正在试图弄清楚Haskell中的迭代I / O是什么。我用一些definitions检查了下面的Haskell-Wiki。

我不明白该函数的第二行,第三行和最后两行的含义:

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函数的作用是什么,但我不理解某些行。 这个wikipage的其他功能真的很神秘。我不明白他们做了什么,因为我错过了一些解释。

2 个答案:

答案 0 :(得分: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处理异常,但事实并非如此。

这有帮助吗?

答案 1 :(得分:2)

如果lambda函数被命名,也许会有所帮助。

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

stepIteratee将继续单步执行文件和iteratee,直到iteratee停止。