Hello fellow Haskellers, this is a proposal to extend the arrow notation (-XArrows). I find myself writing the following very often:
system :: Wire IO () String system = proc _ -> do botAddPeriod <- succ ^<< noise -< () botAddSpeed <- noise1 -< () botAddStart <- noise1 -< () botMsg <- event addBot -< (botAddPeriod, botAddSpeed, botAddStart) bots <- manager -< ((), maybe MgrNop id botMsg) let botStr = concatMap (printf "%8.2") . M.elems $ bots :: String identity -< printf "Bot positions: %s" botStr where addBot :: Wire IO (Double, Double, Double) (MgrMsg Int IO () Double) addBot = proc (addPeriod, addSpeed, addStart) -> do periodically -< addPeriod botId <- identifier -< () identity -< MgrAdd botId (constant addSpeed >>> integral addStart) The relevant part is the first paragraph of the first arrow computation: botAddPeriod <- succ ^<< noise -< () botAddSpeed <- noise1 -< () botAddStart <- noise1 -< () botMsg <- event addBot -< (botAddPeriod, botAddSpeed, botAddStart) This line should generate a message for the bot manager at random intervals. The actual event generator is in the second arrow computation 'addBot'. I would like to be able to write this more in line with the rest of the code. The following is possible: system :: Wire IO () String system = proc _ -> do botAddPeriod <- succ ^<< noise -< () botAddSpeed <- noise1 -< () botAddStart <- noise1 -< () botMsg <- event (proc (addPeriod, addSpeed, addStart) -> do periodically -< addPeriod botId <- identifier -< () identity -< MgrAdd botId (constant addSpeed >>> integral addStart)) -< (botAddPeriod, botAddSpeed, botAddStart) bots <- manager -< ((), maybe MgrNop id botMsg) let botStr = concatMap (printf "%8.2") . M.elems $ bots :: String identity -< printf "Bot positions: %s" botStr This is probably not a big improvement. It's more concise, but also harder to understand. My proposal is to add syntax to allow the following notation: system :: Wire IO () String system = proc _ -> do botAddPeriod <- succ ^<< noise -< () botAddSpeed <- noise1 -< () botAddStart <- noise1 -< () botMsg <- event $ do periodically -< addPeriod botId <- identifier -< () identity -< MgrAdd botId (constant addSpeed >>> integral addStart) bots <- manager -< ((), maybe MgrNop id botMsg) let botStr = concatMap (printf "%8.2") . M.elems $ bots :: String identity -< printf "Bot positions: %s" botStr Again the relevant part is the event generator in the middle. In this hypothetical syntax, the compiler would figure out from the inner computation, which variables from the outer scope are used and pass them automatically in an appropriate tuple. You wouldn't need any explicit passing anymore. If others like the idea, too, and there is nobody to implement it, then I would be willing to get in touch with the GHC code and implement this as a patch myself. What do you think? Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe