如何测试从 GHCi 中的 stdin 读取的程序?

Now*_*man 5 testing io haskell interactive ghci

我的程序有一个我想在 GHCi 中看到的错误:

$ ./my-program < ./my-data
Prelude.foldl1: empty list
Run Code Online (Sandbox Code Playgroud)

我尝试在 GHCi 中更改stdin或 ,getLine但它似乎不会影响getLine我的程序使用,即使我之后加载:

$ ghci
Prelude> import System.IO
Prelude System.IO> getLine <- fmap hGetLine $ openFile "my-data" ReadMode
:l "my-program.hs"
:main
Run Code Online (Sandbox Code Playgroud)

我是否需要重写所有 IO 以获取显式句柄才能在 GHCi 中测试它们?

n. *_* m. 6

您可以尝试将程序包装在类似这样的内容中(经过测试的工作代码):

import qualified System.IO
import qualified GHC.IO.Handle

filename = "/tmp/myfilename"                                                                                                                                                                                                                                                      

main = do                                                                                                                                                                                                                                         
      h <- System.IO.openFile filename System.IO.ReadMode                                                                                                                                                                                         
      old_stdin <- GHC.IO.Handle.hDuplicate System.IO.stdin                                                                                                                                                                                       
      GHC.IO.Handle.hDuplicateTo h System.IO.stdin                                                                                                                                                                                                
      System.IO.hClose h
      realMain
      GHC.IO.Handle.hDuplicateTo old_stdin System.IO.stdin

realMain = ...
Run Code Online (Sandbox Code Playgroud)

还应该可以定义一个用户定义的 GHCi 命令来为任何 GHCi 命令执行此操作,但我还没有尝试过。请参阅此处,了解某人的 .ghci,它使用用户定义的命令重定向命令的标准:redir输出。