<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Dear all,<div class=""><br class=""></div><div class="">In case anyone finds it useful, there is a new version of arrowp in Hackage that improves the original with a much needed coat of fresh paint. Notable features include a new parser based on haskell-src-exts, a quasi quoter for arrow syntax, and improved desugaring for static choices.</div><div class=""><br class=""></div><div class=""><a href="https://github.com/pepeiborra/arrowp" class="">https://github.com/pepeiborra/arrowp</a></div><div class=""><br class=""></div><div class="">The package is in Hackage as **arrowp-qq** due to the impossibility to contact with Ross Paterson (Ross, if you are reading this, please send email!). </div><div class=""><div class=""><br class=""></div><div class=""><a href="https://hackage.haskell.org/package/arrowp-qq" class="">https://hackage.haskell.org/package/arrowp-qq</a></div></div><div class=""><br class=""></div><div class="">For those of you reading this and wondering why would you want to use a preprocessor for something that GHC can already do, the short answer is that you probably don’t.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class="">Using the `proc` quasi quoter</div><div class="">---------------------------</div><div class=""><br class=""></div><div class="">```</div><div class="">addA :: Arrow a => a b Int -> a b Int -> a b Int</div><div class="">addA f g = [proc| x -> do</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>y <- f -< x</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>z <- g -< x</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>returnA -< y + z |]</div><div class="">```</div><div class=""><br class=""></div><div class="">Comparison with **arrowp**</div><div class="">-----------------------</div><div class="">**arrowp-qq** extends the original **arrowp** in three dimensions:</div><div class="">1. It replaces the `haskell-src` based parser with one based on `haskell-src-exts`, which handles most of GHC 8.0.2 Haskell syntax.</div><div class="">2. It provides not only a preprocessor but also a quasiquoter, which is a better option in certain cases.</div><div class="">3. It extends the desugaring to handle static conditional expressions (currently only if-then-else). Example:</div><div class="">```</div><div class="">proc inputs -> do</div><div class=""> results <- processor -< inputs</div><div class=""> if outputResultsArg</div><div class=""> then outputSink -< results</div><div class=""> else returnA -< ()</div><div class=""> returnA -< results</div><div class="">```</div><div class="">The standard **arrowp** (and GHC) desugaring for this code is:</div><div class="">```</div><div class=""> = ((processor >>> arr (\ results -> (results, results))) >>></div><div class=""> (first</div><div class=""> (arr</div><div class=""> (\ results -> if outputResultsArg then Left results else Right ())</div><div class=""> >>> (outputSink ||| returnA))</div><div class=""> >>> arr (\ (_, results) -> results)))</div><div class="">```</div><div class="">This requires an `ArrowChoice`, but there is a more efficient desugaring which </div><div class="">performs the choice at compile time and thus an `Arrow` suffices:</div><div class="">```</div><div class="">((processor >>> arr (\ results -> (results, results))) >>></div><div class=""> (first</div><div class=""> (if outputResultsArg then outputSink else arr (\ results -> ()))</div><div class=""> >>> arr (\ (_, results) -> results)))</div><div class="">```</div><div class=""><br class=""></div><div class="">Comparison with **GHC**</div><div class="">-----------------------</div><div class="">The GHC desugarer does not do a very good job of minimizing the number of</div><div class="">`first` calls inserted. In certain `Arrow` instances, this can have a material effect</div><div class="">on performance. Example:</div><div class="">```</div><div class="">trivial = proc inputs -> do</div><div class=""> chunked <- chunk -< inputs</div><div class=""> results <- process -< chunked</div><div class=""> returnA -< results</div><div class="">```</div><div class="">This code ought to desugar to a chain of arrows, and indeed, both arrowp and</div><div class="">arrowp-qq desugar this to:</div><div class="">```</div><div class="">trivial = chunk >>> process</div><div class="">```</div><div class="">However GHC will produce (approximately) the following code:</div><div class="">```</div><div class=""> arr(\inputs -> (inputs,inputs)) >>> first chunk >>> first process >>> arr fst</div><div class="">```</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jose Iborra</div></body></html>