我最近安装了Leksah(在Windows 7 64位上为0.10.0.4),这对于Haskell来说似乎是一个有趣的IDE。但是,当使用用户输入程序时,我显然忽略了一些东西。
我有一个非常简单的
do
printStr "Prompt: "
x <- readLn
阻止我的代码。当调试器访问readLn时,我希望能够在某处提供输入。但是,我找不到任何输入窗口。我一开始期望可以启用日志窗口,但我无法找到与程序交互的任何地方。在GHCi中运行一切都如预期的那样,所以我确定它不是代码。
此外,当我只执行“Package-&gt; Run”时,在某些其他日志输出到达之前(例如进行重建),提示不会显示。
过去在Linux上使用Emacs和Haskell模式,我希望获得更加用户友好的体验,这样我就可以让一些Windows程序员参与Haskell主题。我错过了什么吗?
答案 0 :(得分:4)
来自这个帖子 http://groups.google.com/group/leksah/browse_thread/thread/7d3e3bf64e56f190/30278795c23b2168
这是一个我们尚未解决的已知问题。我们将GCHi命令发送到它的stdin,但我们也没有好办法在那里发送用户输入。
我不确定应该如何解决这个问题。我们无法使用命令通道将用户输入发送到正在调试的进程(我们的代码在发送命令之前等待来自ghci的提示)。
如果我们设置某种方式将数据发送到stdin而不等待它可能会干扰我们发送的GHCi命令(因为它仍然都在同一个管道中)。
我们需要找出是否有某种方法可以为GHCi本身提供单独的stdin / stdout / stderr管道,而GHCi程序正在调试。
与此同时,您可以让应用程序打开套接字或命名管道,并将输入写入另一个终端的输入。这样的事情(未经测试)......
main = do
sock <- listenOn (PortNumber 8000)
-- Start a new terminal window (this command needs to be changed for OS X or Windows)
forkIO $ system "gnome-terminal -e \"telnet localhost 8000\""
(handle, _, _) <- accept sock -- Wait for the new terminal to connect
-- You might want to add a call to hSetBuffering here
line <- hGetLine handle
print line
sClose sock
(您需要将流程和网络添加到您的软件包依赖项中。然后Ctrl + R应该添加所需的import语句。)
这将允许互动,但保持stdin明确leksah与ghci交谈。理想情况下,你也会保持stdout和stderr的清晰,然后写入这个套接字,但Leksah应该能很好地处理任意输出。
答案 1 :(得分:2)
我遇到了同样的问题,我考虑使用C预处理器来确定我是否需要假输入进行测试。这些方面的东西:
{-# LANGUAGE CPP, TemplateHaskell #-}
module Main (
main
) where
#define FAKE_INPUT
main :: IO ()
main = do
putStrLn "Prompt: "
x <- myReadLn
putStrLn x
#ifdef FAKE_INPUT
myReadLn = return "fake string"
#else
myReadLn = readLn
#endif
当您想要使用真实函数(Leksah之外)进行测试时,可以注释#defines FAKE_INPUT的行。您也可以获得多种输入,并且有多个常量用于多个输入,但最终可能是单元测试,这可能是最终的最佳解决方案。
答案 2 :(得分:0)
我不使用Leksah,因此我无法回答您问题的那一部分,但是使用Package -> Run
时的问题是由提示保存在缓冲区而不是立即输出引起的。
默认输出缓冲模式是实现定义的,但对于终端,它通常是行缓冲,这意味着只要向其添加换行符就将缓冲区刷新到输出,而GHCi缓冲通常是禁用的。
由于在提示触发刷新线缓冲模式后没有换行符,因此您需要自己hFlush stdout
或hSetBuffering stdout NoBuffering
完全禁用缓冲。
有关详细信息,请参阅System.IO buffering operations。