У меня есть следующая программа на C:
#include <stdio.h>
#include <unistd.h>
void readAndEchoAll(void) {
for(;;) {
char buf[100];
ssize_t size = read(STDIN_FILENO, buf, sizeof(buf));
if(size <= 0) {
return;
}
fwrite(buf, 1, size, stdout);
}
}
int main(void) {
puts("Reading and echoing STDIN until first EOF...");
readAndEchoAll();
puts("Got first EOF. Now reading and echoing STDIN until second EOF...");
readAndEchoAll();
puts("Got second EOF.");
return 0;
}
Когда я ее запускаю, она работает так, как я хочу.Вот что он делает:
Reading and echoing STDIN until first EOF...
asdf
^Dasdf
Got first EOF. Now reading and echoing STDIN until second EOF...
fdsa
^Dfdsa
Got second EOF.
Я пытаюсь создать эквивалентную программу на Haskell.Вот моя попытка:
readAndEchoAll :: IO ()
readAndEchoAll = do
buf <- getContents
putStr buf
main :: IO ()
main = do
putStrLn "Reading and echoing STDIN until first EOF..."
readAndEchoAll
putStrLn "Got first EOF. Now reading and echoing STDIN until second EOF..."
-- ???
readAndEchoAll
putStrLn "Got second EOF."
Это не работает.Вот что он делает:
Reading and echoing STDIN until first EOF...
asdf
^Dasdf
Got first EOF. Now reading and echoing STDIN until second EOF...
readtwice.hs: <stdin>: hGetContents: illegal operation (handle is closed)
Как мне заставить эту работу работать как программа на C? Я предполагаю, что мне нужно положить какой-то эквивалент clearerr(stdin);
туда, где у меня есть -- ???
, но я не уверен, что это за эквивалент.
Обновление: Оказывается, clearerr
- немного красной селедки, поскольку она исключительна для стандартного C API.При использовании POSIX API вы можете просто читать снова, не делая ничего эквивалентного этому.Поэтому вместо того, чтобы заставлять Haskell делать что-то еще, мне нужно заставить его ничего не делать: не предотвращать дальнейшие чтения, когда он увидит EOF.