7

私は最近 Leksah (Windows 7 64 ビットでは 0.10.0.4) をインストールしました。これは、Haskell の興味深い IDE のようです。ただし、プログラムを使用するときのプログラムへのユーザー入力に関しては、明らかに何かを見落としています。

私は非常に単純です

do
    printStr "Prompt: "
    x <- readLn

私のコードでブロックします。デバッガーが readLn に到達すると、どこかに入力を提供できると期待します。ただし、入力ウィンドウが見つかりません。最初はログ ウィンドウが有効になっているのではないかと思っていましたが、プログラムを操作する場所が見つかりません。GHCi での実行はすべて期待どおりなので、コードではないことは確かです。

さらに、「パッケージ->実行」を実行しただけでは、他のログ出力(再構築など)が到着するまでプロンプトが表示されません。

過去に Linux で Haskell モードで Emacs を使用したことがあるので、Haskell のトピックについて Windows プログラマーと交流できるように、よりユーザー フレンドリーなエクスペリエンスを期待していました。何か不足していますか?

4

3 に答える 3

4

このスレッドから http://groups.google.com/group/leksah/browse_thread/thread/7d3e3bf64e56f190/30278795c23b2168

これは、まだ対処されていない既知の問題です。GCHi コマンドを stdin に送信しますが、そこにもユーザー入力を送信する良い方法がありません。

これをどのように修正すればよいかわかりません。コマンド チャネルを使用してデバッグ中のプロセスにユーザー入力を送信することはできません (コードは、コマンドを送信する前に ghci からのプロンプトを待ちます)。

待機せずに stdin にデータを送信する方法を設定すると、送信する 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 と通信できるように stdin を明確に保ちます。理想的には、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 に答える