<font class="Apple-style-span" face="arial, helvetica, sans-serif">Hello,</font><div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">One issue I can see with such a change is that now it is not obvious which declarations define methods in the instance, and which are just helper functions.  For example, currently, if I mistype the name of a method in a class (which happens often), the program is rejected because there is no such method in the class.  With this change, the program would be accepted because the method would be &quot;undefined&quot; and the mistyped implementation would be considered as just another local declaration.</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">I have also encountered the underlying problem that you describe---wanting more control over the scoping of declarations.  Perhaps we should extend Haskell with something like ML&#39;s &quot;local&quot; declarations: local D1 in D2.  Such a declaration defines what D2 defines, but the implementations in D2 may use the names defined in D1 (i.e., it is like a &quot;let&quot; which scopes over declarations rather then expressions).   This would help with your problem:</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">instance Num Wrapped where</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">   local</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">     lift2 f (Wrapped a) (Wrapped b) = Wrapped (f a b)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">     lift f (Wrapped a) = Wrapped (f a)</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">   in </font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    (+) = lift2 (+)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    (-) = lift2 (-)</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    (*) = lift2 (*)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    abs = lift abs</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    signum = lift signum</font></div>
<div><br></div><div>It would also be useful in other situations.  For example, currently if we have a module which exports most of its functions but not all, we have to write a long export list.  This could be avoided with a local declaration:</div>
<div><br></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">module M where</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">local</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">  not exported functions</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">in</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">  exported functions</font><br>
<br></div><div>Of course, one could also scope the private functions more precisely.  I am not sure what would be good syntax for a concrete proposal but I think that this is a nice construct to have.</div><div><br></div>
<div>-Iavor</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br><div class="gmail_quote">On Thu, Jan 27, 2011 at 3:07 AM, Boris Lykah <span dir="ltr">&lt;<a href="mailto:lykahb@gmail.com">lykahb@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">I think it would be convenient to allow adding variables and<br>
functions, which are not members of the class,  to a class instance so<br>
that they are visible only in the instance scope. It will help if the<br>
same functions are used by several class functions.<br>
<br>
Example:<br>
When implementing Num class for my datatype, I found that I routinely<br>
do unwrapping in each operator definition. I extracted it into<br>
functions, but as they are used only in instance definition, I want to<br>
put them there and restrict them to that scope. It would be neater<br>
than leaving them in the global scope or copypasting into each<br>
operator.<br>
<br>
&gt; newtype Wrapped = Wrapped Integer deriving (Show, Eq)<br>
<br>
&gt; instance Num Wrapped where<br>
&gt;   (+) = lift2 (+)<br>
&gt;   (-) = lift2 (-)<br>
&gt;   (*) = lift2 (*)<br>
&gt;   abs = lift abs<br>
&gt;   signum = lift signum<br>
&gt;   fromInteger = Wrapped<br>
&gt;   lift2 f (Wrapped a) (Wrapped b) = Wrapped (f a b)<br>
&gt;   lift f (Wrapped a) = Wrapped (f a)<br>
<br>
The extension implementation should be very simple.<br>
<font color="#888888"><br>
--<br>
Regards,<br>
Boris<br>
<br>
_______________________________________________<br>
Haskell-prime mailing list<br>
<a href="mailto:Haskell-prime@haskell.org">Haskell-prime@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-prime" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-prime</a><br>
</font></blockquote></div><br></div>