<br><div><span class="gmail_quote">On 10/29/07, <b class="gmail_sendername">Tim Newsham</b> &lt;<a href="mailto:newsham@lava.net">newsham@lava.net</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I would love to have the ability to define binary operator modifiers.<br>For example:<br><br>&nbsp;&nbsp; f \overline{op} g&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = liftM2 op f g<br>&nbsp;&nbsp; f \overleftarrow{op} n&nbsp;&nbsp;= liftM2 op f (return n)<br>&nbsp;&nbsp; n \overrightarrow{op} g = liftM2 op (return n) f
<br>&nbsp;&nbsp; \widehat{f} x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = liftM f x<br><br>so that for example you could define functions like:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;(*3) \overline{+} (/2)<br><br>and<br><br>&nbsp;&nbsp;&nbsp;&nbsp;3 \overrightarrow{+} \widehat{read} getContents<br><br>Obviously you could write this out the long way:
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;liftM2 (3+) $ liftM read getContents<br><br>or go through the trouble of defining a bunch of binops<br><br>&nbsp;&nbsp;&nbsp;&nbsp;f &lt;+&gt; g = liftM2 (+) f g<br>&nbsp;&nbsp;&nbsp;&nbsp;n +&gt;&nbsp;&nbsp;g = return n &lt;+&gt; g<br>&nbsp;&nbsp;&nbsp;&nbsp;f &lt;+&nbsp;&nbsp;n = f &lt;+&gt; return n
<br>&nbsp;&nbsp;&nbsp;&nbsp;read&#39; = liftM read<br><br>&nbsp;&nbsp;&nbsp;&nbsp;(*3) &lt;+&gt; (/2)<br>&nbsp;&nbsp;&nbsp;&nbsp;3 +&gt; read&#39; getContents<br><br>but doing this for more than one or two operators gets tedious<br>quickly...<br><br>Is there any way in Haskell to modify binops in this way and still
<br>be able to use them infix?&nbsp;&nbsp;If not, has anyone considered supporting<br>strange syntaxes like this?</blockquote><div><br>I&#39;ve wanted this at times, too, due to using a lot of J a year or so ago.&nbsp; J has some weird parsing/semantics rules so that f g h essentially means liftM2 g f h.&nbsp; For example, avg =. +/ % #&nbsp;&nbsp; is the J equivalent of avg = liftM2 (/) sum length.&nbsp; Anyway, the closest you can get in Haskell is something like this, using the 
<a href="http://www.haskell.org/pipermail/haskell-cafe/2002-July/003215.html">infix expressions of Ken Shan and Dylan Thurston</a>:<br><br>import Control.Monad<br>import Control.Monad.Instances<br><br>infixr 0 -:, :-<br><br>
data Infix f y = f :- y<br>x -: f :- y = x `f` y<br><br>ov op = liftM2 op<br>ovL op f n = liftM2 op f (return n)<br>ovR op n f = liftM2 op (return n) f<br>hat f = liftM f<br><br>*Main&gt; :t (*3) -:ov (+):- (/2)<br>(*3) -:ov (+):- (/2) :: forall a1. (Fractional a1) =&gt; a1 -&gt; a1
<br>*Main&gt; ((*3) -:ov (+):- (/2)) 7<br>24.5<br>*Main&gt; :t 3 -:ovR (+):- ((hat read) getContents)<br>3 -:ovR (+):- ((hat read) getContents) :: forall a. (Num a, Read a) =&gt; IO a<br><br>It works (?), but it&#39;s pretty ugly and hardly seems worth it, unfortunately.
<br><br>-Brent</div></div>