我不明白为什么这段代码只循环一次然后退出? 在Ghci我只能回答第一个循环,然后似乎变量cont设置为false,我没有提示回答。
结果是:
*Main> testLoop1 td10
test
Do you want to continue? (y/N)
y
we continue
test
Do you want to continue? (y/N)
We stop
代码:
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 ()
答案 0 :(得分:15)
问题在于,当您键入y
并按Enter键时,实际上正在输入两个字符:'y'
本身,以及通过按返回来发送的换行符键。第一轮,循环看到'y'
,但下一轮,它会看到'\n'
,而'\n'
不是'y'
,它会退出。< / p>
您可以在进入循环之前执行hSetBuffering stdin NoBuffering
(您需要导入System.IO
),这样您就可以在不等待换行符的情况下处理字符,或者一次专门处理行:
continue = do
putStrLn "Do you want to continue? (y/N)"
s <- getLine
return $ s == "y"
顺便说一下,您可以只使用liftIO $ testLoop1 td
代替loop1
,而不是写testLoop1
,而是可以使用testLoop1 = evalStateT loop1
替换它。
另外,evalStateT
最好写成:
runStateT
>> return ()
与{{1}}类似,但不包含最终状态,因此您无需使用{{1}}明确丢弃该值。