将Leksah调试器与使用readLn和类似程序的程序一起使用

时间:2011-09-15 02:21:42

标签: haskell windows-7 leksah

我最近安装了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主题。我错过了什么吗?

3 个答案:

答案 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 stdouthSetBuffering stdout NoBuffering完全禁用缓冲。

有关详细信息,请参阅System.IO buffering operations