我正在试图弄清楚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的其他功能真的很神秘。我不明白他们做了什么,因为我错过了一些解释。
答案 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停止。