继续读取用户键盘输入(如果可用),同时回显最新可用的
Keep reading user keyboard input if available, while echoing back the latest available
以下代码一直在等待用户输入,并在获取时将其回显到屏幕。然后它返回等待输入模式。当它处于这种状态时,它会不断地在屏幕上写一条消息。
import Control.Concurrent
import Data.Maybe
import System.IO
main = do
hSetBuffering stdin NoBuffering
future_input <- newEmptyMVar
forkIO $ (>>) <$> putMVar future_input
<*> (putStrLn . ("pressed key: " ++) . return)
=<< getChar
wait future_input
where wait future_input = do
input <- tryTakeMVar future_input
if isJust input
then main
else putStrLn "keep waiting" >> threadDelay 1000000 >> wait future_input
我想获得的是消息 keep waiting
伴随着 可用的 用户输入。
到目前为止我唯一的想法是我应该
- 与
future_input
一起声明另一个MVar
、latest_input
- 让分叉线程与
future_input
同时填写
- 在
if isJust input
的 else
中,我应该从 latest_input
tryTakeMVar
并且,如果其中有内容(即,根据第 2 点,总是这样,除了第一次),我可以在输出中使用它。
然而,在我这个冒昧的想法中,我认为我也应该让 wait
拿走两个 MVar
,因为我在等待时不必失去对他们中任何一个的追踪。同样,即使在 if isJust input
的 then
分支中,我也可能会传递 latest_input
,这意味着我必须使用 main
以外的函数,它会被 main
.
现在,我已经到了这里:
import Control.Concurrent
import Data.Maybe
import System.IO
main = do
hSetBuffering stdin NoBuffering
future_input <- newEmptyMVar
latest_input <- newEmptyMVar
forkIO $ ((>>) .) . (>>)
<$> putMVar future_input
<*> putMVar latest_input
<*> (putStrLn . ("pressed key: " ++) . return)
=<< getChar
wait future_input
where wait future_input = do
input <- tryTakeMVar future_input
if isJust input
then main
else putStrLn "keep moving" >> threadDelay 1000000 >> wait future_input
呃,我想我明白了 :D(我已经把它放在 Code Review 中了)。
import Control.Concurrent
import Data.Maybe
import System.IO
main = do
hSetBuffering stdin NoBuffering
future_input <- newEmptyMVar
latest_input <- newEmptyMVar
putMVar latest_input 'A' -- assuming a previous input the first time
work future_input latest_input
work :: MVar Char -> MVar Char -> IO ()
work future_input latest_input = do
forkIO $ ((>>) .) . (>>)
<$> putMVar future_input
<*> tryPutMVar latest_input
<*> (putStrLn . ("pressed key: " ++) . return)
=<< getChar
wait future_input latest_input
where wait future_input latest_input = do
input <- tryTakeMVar future_input
old_input <- takeMVar latest_input
if isJust input
then do
putMVar latest_input (fromJust input)
work future_input latest_input
else do
putMVar latest_input old_input
putStrLn ("latest input was " ++ (return old_input))
>> threadDelay 1000000
>> wait future_input latest_input
以下代码一直在等待用户输入,并在获取时将其回显到屏幕。然后它返回等待输入模式。当它处于这种状态时,它会不断地在屏幕上写一条消息。
import Control.Concurrent
import Data.Maybe
import System.IO
main = do
hSetBuffering stdin NoBuffering
future_input <- newEmptyMVar
forkIO $ (>>) <$> putMVar future_input
<*> (putStrLn . ("pressed key: " ++) . return)
=<< getChar
wait future_input
where wait future_input = do
input <- tryTakeMVar future_input
if isJust input
then main
else putStrLn "keep waiting" >> threadDelay 1000000 >> wait future_input
我想获得的是消息 keep waiting
伴随着 可用的 用户输入。
到目前为止我唯一的想法是我应该
- 与
future_input
一起声明另一个 - 让分叉线程与
future_input
同时填写
- 在
if isJust input
的else
中,我应该从latest_input
tryTakeMVar
并且,如果其中有内容(即,根据第 2 点,总是这样,除了第一次),我可以在输出中使用它。
MVar
、latest_input
然而,在我这个冒昧的想法中,我认为我也应该让 wait
拿走两个 MVar
,因为我在等待时不必失去对他们中任何一个的追踪。同样,即使在 if isJust input
的 then
分支中,我也可能会传递 latest_input
,这意味着我必须使用 main
以外的函数,它会被 main
.
现在,我已经到了这里:
import Control.Concurrent
import Data.Maybe
import System.IO
main = do
hSetBuffering stdin NoBuffering
future_input <- newEmptyMVar
latest_input <- newEmptyMVar
forkIO $ ((>>) .) . (>>)
<$> putMVar future_input
<*> putMVar latest_input
<*> (putStrLn . ("pressed key: " ++) . return)
=<< getChar
wait future_input
where wait future_input = do
input <- tryTakeMVar future_input
if isJust input
then main
else putStrLn "keep moving" >> threadDelay 1000000 >> wait future_input
呃,我想我明白了 :D(我已经把它放在 Code Review 中了)。
import Control.Concurrent
import Data.Maybe
import System.IO
main = do
hSetBuffering stdin NoBuffering
future_input <- newEmptyMVar
latest_input <- newEmptyMVar
putMVar latest_input 'A' -- assuming a previous input the first time
work future_input latest_input
work :: MVar Char -> MVar Char -> IO ()
work future_input latest_input = do
forkIO $ ((>>) .) . (>>)
<$> putMVar future_input
<*> tryPutMVar latest_input
<*> (putStrLn . ("pressed key: " ++) . return)
=<< getChar
wait future_input latest_input
where wait future_input latest_input = do
input <- tryTakeMVar future_input
old_input <- takeMVar latest_input
if isJust input
then do
putMVar latest_input (fromJust input)
work future_input latest_input
else do
putMVar latest_input old_input
putStrLn ("latest input was " ++ (return old_input))
>> threadDelay 1000000
>> wait future_input latest_input