ghc を使ってちょっと疑問に思う挙動があったので、わかるひとがいましたら
教えてください。

stdin から stdout に 1文字づつコピーする次の プログラムを考えます。こ
れは The Haskell 98 Library Report: IO に載っていたものをちょっと変え
たものです。

% cat tst.hs
module Main where

import IO

main = copyFile stdin stdout

copyFile h1 h2 = do
                   eof <- hIsEOF h1
                   if eof then return () else
                      do
                        c <- hGetChar h1
                        hPutChar h2 c
                        hFlush h2
                        copyFile h1 h2

ghc でコンパイルします。

% ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.2.2
% ghc tst.hs

1秒に 1byte づつ書き込まれる pipe から、このプログラムで読み出します。

% ruby -e 'STDOUT.sync=true; loop { sleep 1; print "a" }'| ./a.out     

ところが、なぜかしばらく待っても出力が出てきません。

しょうがないので strace で調べてみると、

% ruby -e 'STDOUT.sync=true; loop { sleep 1; print "a" }'| strace ./a.out
...
read(0, 0x402bd008, 8192)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1116764330, 397643}, NULL) = 0
select(1, [0], [], NULL, {134, 217727}) = 1 (in [0], left {133, 370000})
read(0, "a", 8192)                      = 1
read(0, 0x402bd009, 8191)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1116764331, 246756}, NULL) = 0
select(1, [0], [], NULL, {134, 217727}) = 1 (in [0], left {133, 220000})
read(0, "a", 8191)                      = 1
read(0, 0x402bd00a, 8190)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1116764332, 246688}, NULL) = 0
select(1, [0], [], NULL, {134, 217727}) = 1 (in [0], left {133, 220000})
read(0, "a", 8190)                      = 1
read(0, 0x402bd00b, 8189)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1116764333, 246668}, NULL) = 0
...

というように、a.out はちゃんと読み出してはいるようです。

なんで出力されないんでしょう?

少し調べてみると、hIsEOF で止まってる感じなんですが、1byte 読んだ段階
で EOF じゃないことはわかるように思うのですが。
-- 
[田中 哲][たなか あきら][Tanaka Akira]

--
ML: haskell-jp / quickml.com
使い方: http://QuickML.com/