2012-01-23 4 views
5

このコードがループして終了する理由を理解できません。 Ghciの 私は最初のループにしか答えることができませんが、変数contがfalseに設定されているように見え、答えが表示されません。StateTを使用したループ:なぜこのループはループしないのですか

結果は次のとおりです。

*Main> testLoop1 td10 
test 
Do you want to continue? (y/N) 
y 
we continue 
test 
Do you want to continue? (y/N) 
We stop 

コード:'y'自体、:

type TDeckSTIO = StateT TableDecks IO 

continue = do 
putStrLn "Do you want to continue? (y/N)" 
c <- getChar 
return $ c == 'y' 


loop1 :: TDeckSTIO() 
loop1 = do 
    liftIO $ putStrLn "test" 
    cont<- liftIO continue 
    if cont 
    then do 
     liftIO $ putStrLn "we continue" 
     liftIO $ testLoop1 td 

    else liftIO $ putStrLn "We stop" 

testLoop1 td = runStateT (loop1) td >> return() 

答えて

15

問題は、あなたがyを入力し、Enterキーを押したときに、それが実際に文字を入力するということですリターンキーを押すことによって送られる改行文字。最初のラウンドでループは'y'と表示されますが、次回は'\n'と表示され、'\n''y'ではないため終了します。

あなたがループに入る前に、あなたは改行を待たずに文字を処理してみましょうか、特に一度にラインを処理するた、(あなたがSystem.IOをインポートする必要があります)hSetBuffering stdin NoBufferingを行うことができ、次のいずれか

continue = do 
    putStrLn "Do you want to continue? (y/N)" 
    s <- getLine 
    return $ s == "y" 

ちなみに、liftIO $ testLoop1 tdと書くのではなく、同じ状態のモナドに留まることができます。それをloop1と置き換えることができ、まったく同じように動作します。

testLoop1 = evalStateT loop1 

evalStateTrunStateT似ていますが、明示的に>> return()で値を破棄する必要はありませんので、最終状態が含まれていません:として

また、testLoop1が良く書かれています。

+0

おかげさまで私が望んでいたこと以上のことをありがとう。私はコードを変更したばかりのパスを見つけ出し、 '\ n'を表示するプリントを追加しました。 liftIO $ testLoop1 td - > loop1のヒントをありがとう。それは私の以前のテストの1つでした。私はその2つのコードのどれを置き換えるべきか疑問に思っていました。 evalStateとの良い点。それがstatetransformerとIOを使った私の最初の侵入でした。 –

関連する問題