2017-07-10 6 views
2

Je ne connais pas encore Haskell et je ne sais pas exactement comment fonctionne l'E/S simultanée. J'explore ce qui peut être accompli avec les liaisons audio JACK. En gros, le code suivant est (presque) fonctionnelle, mais je dois appuyer sur Entrée deux fois chaque fois que je entrer une valeur:Haskell - Routage d'E/S simultanées

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 

Pour clarifier le problème:

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" 

Je ne suis pas sûr, mais il semblerait que le flux IO passe par des threads. Y at-il un moyen de faire lire le programme à chaque ligne d'entrée, au lieu de toutes les autres lignes?

+1

Je n'arrive pas à reproduire votre problème. S'il vous plaît envisager de faire un MCVE, ce qui inclurait les importations, exclure 'runAudioStuff', et incluez-vous tester l'exemple pour s'assurer qu'il se comporte toujours incorrectement. Ma version se comporte bien - si ce n'est pas le cas, je suppose que c'est un problème avec votre terminal et pas du tout un problème avec Haskell. –

Répondre

0

La mise en œuvre est toujours importante. Il se trouve que runJack appelé waitForBreak dans Sound.JACK, qui a la définition:

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

En utilisant collectInput à sa place a résolu le problème.