<div dir="ltr"><font color="#003333"><font size="2"><font face="verdana,sans-serif">Thanks. I&#39;m still wondering what [ ] refers to. I can load the following file without error.<br><br></font></font></font><div style="margin-left: 40px;">

<font color="#003333"><font size="2"><font face="verdana,sans-serif">null&#39; xs = xs == [ ]</font></font></font><br><br><font color="#003333"><font size="2"><font face="verdana,sans-serif">test = </font></font></font><br>

<font color="#003333"><font size="2"><font face="verdana,sans-serif">   let x = [ ] </font></font></font><br><font color="#003333"><font size="2"><font face="verdana,sans-serif">   in tail [1]  == x &amp;&amp; </font></font></font><font color="#003333"><font size="2"><font face="verdana,sans-serif">tail [&#39;a&#39;]  == x  </font></font></font><br>

</div><font color="#003333"><font size="2"><font face="verdana,sans-serif"><br></font></font></font><font color="#003333"><font size="2"><font face="verdana,sans-serif">(I know I can define null&#39; differently. I&#39;m defining it this way so that I can ask this question.)<br>

<br></font></font></font><font color="#003333"><font size="2"><font face="verdana,sans-serif">When I execute test I get True.<br></font></font></font><div style="margin-left: 40px;"><font color="#003333"><font size="2"><font face="verdana,sans-serif"> &gt; test</font></font></font><br>

<font color="#003333"><font size="2"><font face="verdana,sans-serif"> True</font></font></font><br></div><font color="#003333"><font size="2"><font face="verdana,sans-serif"><br></font></font></font><font style="font-family: verdana,sans-serif; color: rgb(0, 51, 51);" color="#003333" size="2">So my question is: what is x after compilation? Is it really a thing of type <br>

     (Eq a) =&gt; [a] ? <br>If so, how should I think of such a thing being stored so that it can be found equal to both tail [1] and tail [&#39;a&#39;]?  Furthermore, this seems to show that (==) is not transitive since one can&#39;t even compile</font><font style="font-family: verdana,sans-serif; color: rgb(0, 51, 51);" color="#003333" size="2"><br>

  tail [1] == tail [&#39;a&#39;]</font><font style="color: rgb(0, 51, 51);" size="2"><br style="font-family: verdana,sans-serif;"><span style="font-family: verdana,sans-serif;">much less find them to be equal. </span></font><font style="font-family: verdana,sans-serif; color: rgb(0, 51, 51);" color="#003333" size="2">Yet they are each == to x.<br>

</font><font style="color: rgb(0, 51, 51);" size="2"><br style="font-family: verdana,sans-serif;"></font><div dir="ltr"><font style="color: rgb(0, 51, 51); font-family: verdana,sans-serif;" size="2"><span style="font-family: verdana,sans-serif; color: rgb(0, 51, 51);">-- Russ </span><br>

</font></div><br>
<br><br><div class="gmail_quote">On Fri, Oct 1, 2010 at 9:08 AM, Daniel Fischer <span dir="ltr">&lt;<a href="mailto:daniel.is.fischer@web.de">daniel.is.fischer@web.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<div><div></div><div class="h5">On Friday 01 October 2010 17:08:08, Russ Abbott wrote:<br>
&gt; Thanks, Filipe<br>
&gt;<br>
&gt; I clearly over-stated my case.  I&#39;d like to break it into a number of<br>
&gt; different question.  Please see below.<br>
&gt;<br>
&gt; On Thu, Sep 30, 2010 at 10:25 PM, Felipe Lessa<br>
&lt;<a href="mailto:felipe.lessa@gmail.com">felipe.lessa@gmail.com</a>&gt;wrote:<br>
&gt; &gt; I&#39;ll try to clarify some concepts.  Please correct me if I am<br>
&gt; &gt; wrong, and please forgive me if I misunderstood you.<br>
&gt; &gt;<br>
&gt; &gt; On Fri, Oct 1, 2010 at 12:54 AM, Russ Abbott &lt;<a href="mailto:russ.abbott@gmail.com">russ.abbott@gmail.com</a>&gt;<br>
&gt; &gt;<br>
&gt; &gt; wrote:<br>
&gt; &gt; &gt; In explaining fromIntegral, I want to say that it is really a<br>
&gt; &gt; &gt; collection<br>
&gt; &gt;<br>
&gt; &gt; of<br>
&gt; &gt;<br>
&gt; &gt; &gt; overloaded functions:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Integer -&gt; Double<br>
&gt; &gt; &gt; Int -&gt; Float<br>
&gt; &gt; &gt; ...<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; When GHC compiles a line of code with fromIntegral it in, it must<br>
&gt; &gt; &gt; decide<br>
&gt; &gt;<br>
&gt; &gt; at<br>
&gt; &gt;<br>
&gt; &gt; &gt; compile time which of these overloaded functions to compile to.<br>
&gt; &gt; &gt; This is<br>
&gt; &gt;<br>
&gt; &gt; in<br>
&gt; &gt;<br>
&gt; &gt; &gt; contrast to saying that fromIngetral is a function of the type<br>
&gt; &gt; &gt; (Integral<br>
&gt; &gt;<br>
&gt; &gt; a,<br>
&gt; &gt;<br>
&gt; &gt; &gt; Num b) =&gt; a -&gt; b.  In reality there is no (single) function of the<br>
&gt; &gt; &gt; type (Integral a, Num b) =&gt; a -&gt; b because (among other things)<br>
&gt; &gt; &gt; every function must map between actual types, but (Integral a, Num<br>
&gt; &gt; &gt; b) =&gt; a -&gt; b does not say which actual types are mapped between.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Is the preceding a reasonable thing to say?<br>
&gt; &gt;<br>
&gt; &gt; First of all, I do think that polymorphic functions are plain ol&#39;<br>
&gt; &gt; functions.  For example<br>
&gt; &gt;<br>
&gt; &gt;  id :: a -&gt; a<br>
&gt; &gt;  id x = x<br>
&gt; &gt;<br>
&gt; &gt; is a function.  Moreover, in GHC &#39;id&#39; has only one<br>
&gt; &gt; representation, taking a thunk and returning a thunk, so even at<br>
&gt; &gt; the machine code level this is only one function.<br>
&gt;<br>
&gt; Agree.  I over stated my case.  The same can be said for<br>
&gt;   length  :: [a] -&gt; Int<br>
&gt; It doesn&#39;t matter what the type of element in the list is. length runs<br>
&gt; the same way no matter what. So this is pure polymorphism.<br>
&gt;<br>
&gt; &gt; Now, maybe &#39;fromIntegral&#39; has something more than polymorphism?<br>
&gt; &gt; Well, it has typeclasses.  But we can represent those as<br>
&gt; &gt; data types, so we could write<br>
&gt; &gt;<br>
&gt; &gt;  fromIntegralD :: Integral a -&gt; Num b -&gt; a -&gt; b<br>
&gt; &gt;  fromIntegralD intrDictA numDictB =<br>
&gt; &gt;    fromIntegral numDictB . toInteger intrDictA<br>
&gt;<br>
&gt; I&#39;m afraid I don&#39;t understand this. Moreover, I couldn&#39;t get the<br>
&gt; preceding to load without error.<br>
&gt;<br>
<br>
</div></div>No wonder, Integral and Num are type classes and not datatypes (unless you<br>
have defined such datatypes in scope).<br>
<br>
The point is, you can represent type classes as dictionaries, e.g.<br>
<br>
data Num a = NumDict<br>
    { plus :: a -&gt; a -&gt; a<br>
    , minus :: a -&gt; a -&gt; a<br>
    , ...<br>
    , fromIntegerD :: Integer -&gt; a<br>
    }<br>
<br>
data Integral a = IntegralDict<br>
    { quotD :: a -&gt; a -&gt; a<br>
    , ...<br>
    , toIntegerD a<br>
    }<br>
<br>
Then a type-class polymorphic function like fromIntegral becomes a function<br>
with some dictionaries as additional arguments.<br>
<br>
foo :: (Class1 a, Class2 b) =&gt; a -&gt; b<br>
<br>
becomes<br>
<br>
fooDict :: Class1Dict a -&gt; Class2Dict b -&gt; a -&gt; b<br>
<br>
To do that explicitly is of course somewhat cumbersome as one has to always<br>
carry the dictionaries around and one can have more than one dictionary per<br>
type (e.g.<br>
<br>
intNum1 :: Num Int<br>
intNum1 = NumDict<br>
    { plus = (+)<br>
    , ...<br>
    , fromIntegerD = fromInteger<br>
    }<br>
<br>
intNum2 :: Num Int<br>
intNum2 = NumDict<br>
    { plus = quot<br>
    , -- more nonsense<br>
    , fromInteger = const 1<br>
    }<br>
).<br>
<br>
Internally, GHC implements type classes via dictionaries and passes them as<br>
extra arguments to overloaded functions, as you can see by inspecting the<br>
Core output (-ddump-simpl).<br>
<div class="im"><br>
&gt; &gt; Better yet, the compiler could write this code for us internally.<br>
<br>
</div>And GHC does.<br>
<div class="im"><br>
&gt; &gt; Now, using thunks we can get a single machine code for<br>
&gt; &gt; &#39;fromIntegralD&#39; as well.<br>
<br>
</div>But that&#39;s not terribly efficient, so with -O, GHC tries to eliminate<br>
dictionaries and use the specialised functions (like<br>
plusInteger :: Integer -&gt; Integer -&gt; Integer).<br>
<div class="im"><br>
&gt; &gt;<br>
&gt; &gt; In sum, I think all functions are really just that, functions.<br>
&gt; &gt;<br>
&gt; &gt; --<br>
&gt; &gt;<br>
&gt; &gt; You may call functions that have typeclass constraints<br>
&gt; &gt; &quot;overloaded functions&quot;, but they still are functions.<br>
&gt; &gt;<br>
&gt; &gt; Functions that are polymorphic but do not have constraints are<br>
&gt; &gt; not really overloaded because of parametricity, which means that<br>
&gt; &gt; they can&#39;t change the way they work based on the specific choices<br>
&gt; &gt; of types you make.<br>
&gt;<br>
&gt; I don&#39;t understand the preceding paragraph. Would you mind elaborating.<br>
&gt;<br>
<br>
</div>For a function like<br>
<br>
length :: [a] -&gt; Int<br>
<br>
, because it doesn&#39;t know anything about the type a at which it will be<br>
called, it cannot do anything with the contents of the list (well, it could<br>
call seq on them, but it would do that for every type), it can only inspect<br>
the spine of the list.<br>
<br>
The code is completely independent of what type of data the pointers to the<br>
contents point to, so `length [True,False]&#39; and `length [()]&#39; can and do<br>
call the exact same machine code.<br>
<div class="im"><br>
&gt; &gt; &gt; If so, can I say the same sort of thing about constants like 1 and<br>
&gt; &gt; &gt; []? In particular there is no single value []. Instead [] is a<br>
&gt; &gt; &gt; symbol which at compile time must be compiled to the empty list of<br>
&gt; &gt; &gt; some particular type, e.g., [Int].  There is no such Haskell value<br>
&gt; &gt; &gt; as [] :: [a] since [a] (as type) is not an actual type. I want to<br>
&gt; &gt; &gt; say the same thing about 1, i.e., that there is no such Haskell<br>
&gt; &gt; &gt; value as 1 :: (Num t) =&gt; t. When the symbol<br>
&gt; &gt;<br>
&gt; &gt; 1<br>
&gt; &gt;<br>
&gt; &gt; &gt; appears in a program, the compiler must decide during compilation<br>
&gt; &gt; &gt; whether<br>
&gt; &gt;<br>
&gt; &gt; it<br>
&gt; &gt;<br>
&gt; &gt; &gt; is intended to be 1::Int or 1::Integer or 1::Double, etc.<br>
&gt; &gt;<br>
&gt; &gt; Well, [a] *is* an actual type, a polymorphic one.<br>
&gt;<br>
&gt; Here is the example that raised that issue for me. Let&#39;s say I define<br>
&gt; null&#39; as follows.<br>
&gt;<br>
&gt;    null&#39; xs = xs == [ ]<br>
&gt;<br>
&gt; If I don&#39;t include a declaration in the file, Haskell (reasonably)<br>
&gt; concludes the following.<br>
&gt;<br>
&gt;   &gt; :t null&#39;<br>
&gt;<br>
&gt;   null&#39; :: (Eq a) =&gt; [a] -&gt; Bool<br>
&gt;<br>
&gt; If I write the following at the top level,<br>
<br>
</div>You seem to mean the ghci prompt here, not the top level of a module.<br>
<div class="im"><br>
&gt; everything is fine.<br>
&gt;<br>
&gt;   &gt; null&#39; [ ]<br>
&gt;<br>
&gt;   True<br>
&gt;<br>
&gt; But if I include the following in the file that defines null&#39;, I get an<br>
&gt; error message.<br>
&gt;<br>
&gt;   test = null&#39; [ ]<br>
&gt;<br>
&gt;       Ambiguous type variable `a&#39; in the constraint:<br>
&gt;            `Eq a&#39; arising from a use of `null&#39;&#39; at null.hs:6:17-24<br>
&gt;          Probable fix: add a type signature that fixes these type<br>
&gt; variable(s)<br>
&gt;<br>
&gt; Why is that?<br>
<br>
</div>null&#39; has an Eq constraint, so to evaluate test, an Eq dictionary is<br>
needed, but there&#39;s no way to determine which one should be used.<br>
<br>
At a lower level, the type of null&#39; is<br>
<br>
null&#39; :: EqDict a -&gt; [a] -&gt; Bool<br>
<br>
The (hidden) first argument is missing and GHC doesn&#39;t know which one to<br>
pass.<br>
<br>
At the ghci-prompt, ghci&#39;s extended default rules let it selet the Eq<br>
dictionary of () and all&#39;s fine.<br>
<br>
In a source file, GHC restricts itself to the default rules specified in<br>
the language report, which state that for defaulting to take place, at<br>
least one of the constraints must be a numeric class. There&#39;s none here, so<br>
no defaulting and the type variable of the constraint remains ambiguous.<br>
<div class="im"><br>
&gt; And how can it be fixed?  I know I can fix it as follows.<br>
&gt;<br>
&gt;   test = null&#39; ([ ] :: [Integer])<br>
&gt;<br>
&gt;   &gt; :reload<br>
&gt;   &gt;<br>
&gt;   &gt; test<br>
&gt;<br>
&gt;   True<br>
<br>
</div>In that situation, I think giving a type signature is the only way¹.<br>
<br>
test = null&#39; ([] :: Num a =&gt; [a])<br>
<br>
also works.<br>
<br>
¹ -XExtendedDefaultRules might work too.<br>
<div class="im">&gt;<br>
&gt; That&#39;s what suggested to me that [ ] had to be compiled into a concrete<br>
&gt; value.<br>
<br>
</div>Try<br>
<br>
null&#39;&#39; [] = True<br>
null&#39;&#39; _ = False<br>
<br>
test&#39;&#39; = null&#39;&#39; []<br>
<br>
No type class constraints, no problems.<br>
<div class="im"><br>
&gt;<br>
&gt;<br>
&gt; It seemed to me that similar reasoning applied to things like 1.  How is<br>
&gt; the following explained?<br>
&gt;<br>
&gt;    Prelude&gt; 111111111111111111111111111111111111111111<br>
&gt;    111111111111111111111111111111111111111111<br>
&gt;    it :: (Num t) =&gt; t<br>
&gt;    Prelude&gt; maxBound :: Int<br>
&gt;    2147483647<br>
&gt;    it :: Int<br>
&gt;    Prelude&gt; 111111111111111111111111111111111111111111 - (1::Int)<br>
&gt;    -954437178<br>
&gt;    it :: Int<br>
&gt;<br>
&gt; Does it make sense to say that the long string of 1&#39;s is really of type<br>
&gt; (Num t) =&gt; t?<br>
<br>
</div>Integer literals stand for (fromInteger Integer-value-of-literal), so the<br>
literal itself can have any type belonging to Num. If you force it to have<br>
a particular type, the corresponding fromInteger function is determined and<br>
can be applied if the value is needed.<br>
<div class="im"><br>
&gt;<br>
&gt; If so, what does the compiler think it&#39;s doing when it processes(?) it<br>
&gt; as an Int so that it can subtract 1 :: Int from it?  It didn&#39;t treat it<br>
&gt; as maxBound :: Int.  And yet it didn&#39;t generate an error message.<br>
<br>
</div>For efficiency, fromInteger wraps, for a b-bit Integral type, the result of<br>
fromInteger n is n `mod` 2^b.<br>
<br>
&gt;<br>
&gt; Thanks<br>
&gt;<br>
&gt; -- Russ<br>
<br>
</blockquote></div><br></div>