在haskell中捕获/劫持stdout [英] Catching/hijacking stdout in haskell
问题描述
我怎样才能定义'catchOutput',以便只运行主输出'bar'?我怎样才能访问输出流(stdout)和io action的实际输出是分开的吗?
$ $ $ $ $ $ $ $ $ $ $ catchOutput :: IO a - > IO(a,String)
catchOutput = undefined
doSomethingWithOutput :: IO a - > IO()
doSomethingWithOutput io = do
(_ioOutp,stdOutp)< - catchOutput io
如果stdOutp ==foo
则putStrLnbar
else putStrLn失败!
main = doSomethingWithOutput(putStrfoo)
最好的假设解决方案到目前为止,我发现包括转移标准输出,受此,然后从该文件读取()除了超级丑陋之外,从文件写入之后,我还没有能够直接读取它。是否可以创建一个自定义缓冲流不必存储在文件中?)。尽管这感觉有点像侧轨。另一个角度似乎使用'hGetContents标准输出',如果这应该做我认为应该的。但我没有获得从stdout读取的权限。虽然使用谷歌搜索似乎表明它已被使用。
Hackage上有一些软件包承诺可以做到这一点:io捕获和静默。默默似乎被维护,并在Windows上工作(io捕获只适用于Unix)。默默地,你使用capture:
import System.IO.Silently
main = do
(output,_)< - capture $ putStrhello
putStrLn $ output ++world
请注意,它通过将输出重定向到一个临时文件然后读取它来工作......但是只要它能工作!
How can I define 'catchOutput' so that running main outputs only 'bar'?
That is, how can I access both the output stream (stdout) and the actual output of an io action separately?
catchOutput :: IO a -> IO (a,String)
catchOutput = undefined
doSomethingWithOutput :: IO a -> IO ()
doSomethingWithOutput io = do
(_ioOutp, stdOutp) <- catchOutput io
if stdOutp == "foo"
then putStrLn "bar"
else putStrLn "fail!"
main = doSomethingWithOutput (putStr "foo")
The best hypothetical "solution" I've found so far includes diverting stdout, inspired by this, to a file stream and then reading from that file (Besides being super-ugly I haven't been able to read directly after writing from a file. Is it possible to create a "custom buffer stream" that doesn't have to store in a file?). Although that feels 'a bit' like a side track.
Another angle seems to use 'hGetContents stdout' if that is supposed to do what I think it should. But I'm not given permission to read from stdout. Although googling it seems to show that it has been used.
There are some packages on Hackage that promise to do that : io-capture and silently. silently seems to be maintained and works on Windows too (io-capture only works on Unix). With silently, you use capture :
import System.IO.Silently
main = do
(output, _) <- capture $ putStr "hello"
putStrLn $ output ++ " world"
Note that it works by redirecting output to a temporary file and then read it... But as long as it works !
这篇关于在haskell中捕获/劫持stdout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!