代码之家  ›  专栏  ›  技术社区  ›  Edward

哈斯克尔的“懒鬼IO”?

  •  8
  • Edward  · 技术社区  · 16 年前

    我在Haskell做一个小实验,想知道是否可以利用懒惰来处理IO。我想写一个函数,它接受一个字符串(一个字符列表)并懒洋洋地生成一个字符串。然后,我希望能够从io懒洋洋地为它输入字符,这样每个字符一有空就会被处理,并且在必要的字符有空时就会产生输出。但是,我不太确定是否/如何从io monad中的输入生成一个懒字符列表。

    3 回复  |  直到 15 年前
        1
  •  14
  •   Don Stewart    16 年前

    haskell中的常规字符串io是惰性的。所以你的例子应该是开箱即用的。

    下面是一个使用“interact”函数的示例,该函数将函数应用于惰性字符流:

    interact :: (String -> String) -> IO ()
    

    让我们从输入流中懒洋洋地过滤掉字母“e”(即在恒定空间中运行):

    main = interact $ filter (/= 'e')
    

    如果愿意,还可以使用getcontents和putstr。他们都很懒。

    运行它以从字典中筛选字母“e”:

    $ ghc -O2 --make A.hs
    $ ./A +RTS -s < /usr/share/dict/words
    ...
                   2 MB total memory in use (0 MB lost due to fragmentation)
    ...
    

    所以我们看到它的足迹是2米。

        2
  •  7
  •   C. A. McCann Ravikant Cherukuri    16 年前

    最简单的惰性io方法包括以下函数 interact , readFile , hGetContents ,例如 顿斯 在书中有一个更广泛的讨论 Real World Haskell 你可能会觉得有用。如果内存为我服务,那么所有这些函数最终都是使用 unsafeInterleaveIO 那个 短命的 如果你愿意的话,你也可以用这种方式构建自己的函数。

    另一方面,最好注意 不安全 就是上面说的: 不安全IO . 使用它——或者基于它的函数-- breaks purity and referential transparency . 这允许显然是纯函数(即,不返回 IO 行动)在评估时影响外部世界,从相同的论点和所有其他不愉快的事情中产生不同的结果。实际上,最明智的使用方法 不安全 不会引起问题,简单的错误通常会导致明显的、容易诊断的错误,但是你已经失去了一些很好的保证。

    当然,也有其他选择;你可以在hackage上找到各种各样的库,它们提供受限的, safer lazy IO conceptually different approaches . 然而,考虑到实际使用中很少出现问题,我认为大多数人倾向于使用内置的、技术上不安全的功能。

        3
  •  3
  •   ephemient    16 年前
    unsafeInterleaveIO :: IO a -> IO a
    

    unsafeInterleaveIO 阿洛斯 IO 计算迟迟不做。当传递类型为的值时 IO a , 输入输出 只有当 a 是必须的。这用于实现惰性文件读取,请参见 System.IO.hGetContents

    例如, main = getContents >>= return . map Data.Char.toUpper >>= putStr 是懒惰的;当您将字符馈送到stdin时,您将在stdout上获得字符。

    (这和写作是一样的。) main = interact $ map Data.Char.toUpper ,就像唐斯的回答。)

    推荐文章