7

我最近安装了 Leksah(Windows 7 64 位上的 0.10.0.4),这对于 Haskell 来说似乎是一个有趣的 IDE。但是,在使用程序时,当涉及到用户对程序的输入时,我显然忽略了一些东西。

我有一个非常简单的

do
    printStr "Prompt: "
    x <- readLn

阻止我的代码。当调试器点击 readLn 时,我希望能够在某处提供输入。但是,我找不到任何输入窗口。起初我预计可能会启用日志窗口,但我找不到与程序交互的地方。在 GHCi 中运行一切都符合预期,所以我确定它不是代码。

此外,当我只是执行“Package->Run”时,提示在其他日志输出到达之前不会变得可见(例如进行重建)。

过去在 Linux 上使用 Emacs 和 Haskell 模式,我希望获得更友好的用户体验,这样我就可以让一些 Windows 程序员参与 Haskell 主题。我错过了什么吗?

4

3 回答 3

4

从这个线程 http://groups.google.com/group/leksah/browse_thread/thread/7d3e3bf64e56f190/30278795c23b2168

这是一个我们尚未解决的已知问题。我们将 GCHi 命令发送到它的标准输入,但我们也没有很好的方法在那里发送用户输入。

我不确定我们应该如何解决这个问题。我们无法使用我们的命令通道将用户输入发送到正在调试的进程(我们的代码在发送命令之前等待来自 ghci 的提示)。

如果我们设置了某种方式在不等待的情况下将数据发送到标准输入,它可能会干扰我们发送的 GHCi 命令(因为它仍然都在同一个管道上)。

我们需要确定是否有某种方法可以为 GHCi 本身和 GHCi 正在调试的程序提供单独的 stdin/stdout/stderr 管道。

同时,您可以让您的应用程序打开一个套接字或命名管道,并将输入从另一个终端写入。像这样的东西(未经测试)......

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 应该添加所需的导入语句。)

这将允许交互,但保持标准输入清晰,以便 leksah 与 ghci 对话。理想情况下,您也应该保持 stdout 和 stderr 清晰并写入此套接字,但 Leksah 应该可以很好地处理任意输出。

于 2011-09-15T06:46:25.300 回答
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 的行。您也可以花哨并为多个输入设置多个常量,但这从单元测试开始,这最终可能是最好的解决方案。

于 2013-03-19T07:36:21.330 回答
0

我不使用 Leksah,所以我无法回答您的那部分问题,但是您使用时的问题Package -> Run是由于提示被保存在缓冲区中而不是立即输出引起的。

默认输出缓冲模式是实现定义的,但对于终端,它通常是行缓冲,这意味着每当您向其添加换行符时,缓冲区都会刷新到输出,而在 GHCi 中缓冲通常是禁用的。

由于提示后没有换行符以在行缓冲模式下触发刷新,因此您需要hFlush stdout自己或hSetBuffering stdout NoBuffering完全禁用缓冲。

有关更多详细信息,请参阅System.IO 缓冲操作

于 2011-09-15T04:55:50.257 回答