I am testing a program. Specifically, I am testing a function in isolation. It requires a handle that can be both read and wrote. The problem is, stdin
or stdout
alone can't do the job. I don't want to rewrite my code just because of such a test, nor do I want to have to open up a socket just for a test either. Also, the program isn't usable yet (have the functions are undefined) so I can't just test it by running it.
What is a handle that gets it input from stdin
and output from stdout
in haskell.
At the file descriptor level, stdin is defined to be file descriptor 0, stdout is defined to be file descriptor 1; and stderr is defined to be file descriptor 2.
stdin − It stands for standard input, and is used for taking text as an input. stdout − It stands for standard output, and is used to text output of any command you type in the terminal, and then that output is stored in the stdout stream.
Variable: FILE * stdin. The standard input stream, which is the normal source of input for the program. Variable: FILE * stdout. The standard output stream, which is used for normal output from the program.
stdin / stdout are logical names for open files that are forwarded (or initialized) by the process that has started a given process. Actually, with the standard fork-and-exec pattern the setup of those may occur already in the new process (after fork) before exec is being called.
One simple way to do this is to use a Pipe
to abstract out reads and writes to handles. One type you can use is:
example :: Monad m => Pipe String String m ()
For example, let's say that your original code looked something like this:
original :: IO ()
original = do
str1 <- getLine
str2 <- getLine
putStrLn (str1 ++ str2)
The new pipes
version would look like this:
import Pipes
example :: Monad m => Pipe String String m ()
example = do
str1 <- await
str2 <- await
yield (str1 ++ str2)
Then, you can test it purely like this:
>>> import qualified Pipes.Prelude as Pipes
>>> Pipes.toList (each ["Hello, ", "world!"] >-> example)
["Hello, world!"]
... or you can test it with real input and output:
>>> runEffect $ Pipes.stdinLn >-> example >-> Pipes.stdoutLn
Hello, <Enter>
world!<Enter>
Hello, world!
This lets you keep your main logic pure, and then choose whether or not to run it purely or impurely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With