I know it&#39;s a bit of an &#39;intentionally provocative&#39; title, but with the recent discussions on Arrows I thought it timely to bring this up.<br><br>Most of the conversion from arrow syntax into arrows uses &#39;arr&#39; to move components around. However, arr is totally opaque to the arrow itself, and prevents describing some very useful objects as arrows.<br>
<br>For example, I would love to be able to use the arrow syntax to define objects of this type:<br><br>data Circuit a b where<br>    Const :: Bool -&gt; Circuit () Bool<br>    Wire :: Circuit a a<br>
    Delay :: Circuit a a<br>
    And :: Circuit (Bool,Bool) Bool<br>    Or :: Circuit (Bool,Bool) Bool<br>    Not :: Circuit Bool Bool<br>    Then :: Circuit a b -&gt; Circuit b c -&gt; Circuit a c<br>    Pair :: Circuit a c -&gt; Circuit b d -&gt; Circuit (a,b) (c,d)<br>
    First :: Circuit a b -&gt; Circuit (a,c) (b,c)<br>    Swap :: Circuit (a,b) (b,a)<br>    AssocL :: Circuit ((a,b),c) (a,(b,c))<br>    AssocR :: Circuit (a,(b,c)) ((a,b),c)<br>    Loop :: Circuit (a,b) (a,c) -&gt; Circuit b c<br>
etc.<br><br>Then we can have code that examines this concrete data representation, converts it to VHDL, optimizes it, etc.<br><br>However, due to the presence of the opaque &#39;arr&#39;, there&#39;s no way to make this type an arrow without adding an &#39;escape hatch&#39;<br>
    Arr :: (a -&gt; b) -&gt; Circuit a b<br>which breaks the abstraction: circuit is supposed to represent an actual boolean circuit; (Arr not) is not a valid circuit because we&#39;ve lost the information about the existence of a &#39;Not&#39; gate.<br>
<br>The arrow syntax translation uses arr to do plumbing of variables.  I think a promising project would be to figure out exactly what plumbing is needed, and add those functions to a sort of &#39;PrimitiveArrow&#39; class.  All of these plumbing functions are trivially implemented in terms of &#39;arr&#39;, when it exists, but if it doesn&#39;t, it should be possible to use the arrow syntax regardless.<br>
<br>  -- ryan<br>