2017-07-10 25 views
2

我是Haskell的新手,我不太確定併發I/O是如何工作的。我正在探索可以用JACK音頻綁定完成的事情。基本上,下面的代碼是(幾乎)功能,但我需要按Enter鍵兩次,每次我輸入一個值:Haskell - 並行I/O路由

collectInput :: IORef Double -> IO() 
collectInput freq = forever $ do 
     putStr ">> " 
     hFlush stdout 
     f <- getLine 
     case readMaybe f of 
      Just x -> do 
       putStrLn $ show x 
       writeIORef freq x 
      Nothing -> do 
       putStrLn "Nada" 


main :: IO() 
main = do 
    freq <- newIORef 440 
    _ <- forkIO $ runJackStuff freq 
    collectInput freq 

要澄清的問題:

Input | Result   | Output 
---------------------------------------- 

330 | Frequency changes | ">> 330.0" 
440 | Nothing happens | "" 
220.0 | Frequency changes | ">> 220.0" 
550.0 | Nothing happens | "" 
bleh | Outputs "Nada"  | ">> Nada" 
     | Nothing Happens | "" 
foo | Outputs "Nada"  | ">> Nada" 

我不知道,但似乎IO流是通過線程循環的。有沒有辦法讓程序讀取每一行輸入,而不是每隔一行?

+1

我無法重現您的問題。請考慮製作一個MCVE,這將包括導入,排除'runAudioStuff',並且包括您測試該示例以確保它仍然行爲不正確。我的版本表現良好 - 如果您的版本沒有,那麼我懷疑它是您的終端的問題,而不是Haskell問題。 –

回答

0

執行總是很重要。事實證明,在runJack稱爲Sound.JACK waitForBreak,其中有定義:

waitForBreak :: IO() 
waitForBreak = 
    let go = getLine >> go 
    in go 

使用collectInput在它的地方解決了這個問題。