[Haskell-cafe] Proposal: Subcomputations in arrow notation
Ertugrul Soeylemez
es at ertes.de
Wed Sep 21 21:04:54 CEST 2011
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/
More information about the Haskell-Cafe
mailing list