`stdin`和`stdout`句柄

时间:2014-04-05 01:16:18

标签: haskell stdout stdin handle

我正在测试一个程序。具体来说,我正在单独测试一个函数。它需要一个可以读写的句柄。问题是,仅stdinstdout无法完成工作。我不想仅仅因为这样的测试而重写我的代码,也不想为了测试而打开一个套接字。此外,该程序尚不可用(功能未定义),因此我无法通过运行它来测试它。

什么是从stdin获取输入并从haskell中的stdout输出的句柄。

1 个答案:

答案 0 :(得分:18)

一种简单的方法是使用Pipe抽象出对句柄的读写。您可以使用的一种类型是:

example :: Monad m => Pipe String String m ()

例如,假设你的原始代码看起来像这样:

original :: IO ()
original = do
    str1 <- getLine
    str2 <- getLine
    putStrLn (str1 ++ str2)

新的pipes版本如下所示:

import Pipes

example :: Monad m => Pipe String String m ()
example = do
    str1 <- await
    str2 <- await
    yield (str1 ++ str2)

然后,你可以纯粹像这样测试它:

>>> import qualified Pipes.Prelude as Pipes
>>> Pipes.toList (each ["Hello, ", "world!"] >-> example)
["Hello, world!"]

...或者您可以使用真实的输入和输出进行测试:

>>> runEffect $ Pipes.stdinLn >-> example >-> Pipes.stdoutLn
Hello, <Enter>
world!<Enter>
Hello, world!

这使您可以保持主逻辑纯净,然后选择是纯粹还是不纯粹地运行它。