【问题标题】:Understanding iteratee-functions in Haskell了解 Haskell 中的迭代函数
【发布时间】:2012-07-12 22:51:19
【问题描述】:

我试图弄清楚 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 函数是做什么的,但我不明白一些行。 这个维基页面上的其他功能真的很神秘。我不明白他们在做什么,因为我错过了一些解释。

【问题讨论】:

    标签: haskell enumerator iterate


    【解决方案1】:

    您提到的行不是特定于枚举器/迭代器的,尽管我可以尝试解释它们。


    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 处理异常而这没有。

    这有帮助吗?

    【讨论】:

      【解决方案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 将继续遍历文件和迭代对象,直到迭代对象停止。

      【讨论】:

        猜你喜欢
        • 2012-02-22
        • 2016-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 2021-04-01
        相关资源
        最近更新 更多