简体   繁体   中英

Haskell — Concurrent I/O Routing

I am new to Haskell, and I'm not exactly sure how the concurrent I/O works. I'm exploring what can be accomplished with the JACK audio bindings. Basically, the following code is (almost) functional, but I need to press enter twice every time I input a value:

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

To clarify the problem:

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"

I'm not sure, but it would seem that the IO stream is cycled through threads. Is there a way to make the program read every line of input, instead of every other line?

Implementation always matters. It turns out that runJack called waitForBreak in Sound.JACK, which has the definition:

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

Using collectInput in its place solved the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM