<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On 2011-05-31, at 9:20 PM, Mike Meyer wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>On Tue, 31 May 2011 20:48:41 -0400<br>Jake Penton &lt;<a href="mailto:djp@arqux.com">djp@arqux.com</a>&gt; wrote:<br><br><blockquote type="cite">Greetings. I post here from time to time as I work my way through Real World Haskell. I believe that I have understood most of what I have studied. However, today I ran into something that seems like magic.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I hope it's ok to refer to RWH here, as I believe that the book is very commonly used for learning the language. I'll include the code that is puzzling me here anyway, though.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">On p.310 of RWH we have:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">data Op = Plus | Minus | Mul | Div | Pow<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deriving (Eq, Show)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">data SymbolicManip a = <br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;Number a<br></blockquote><blockquote type="cite"> &nbsp;| Arith Op (SymbolicManip a) (SymbolicManip a)<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;deriving (Eq, Show)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">instance Num a =&gt; Num (SymbolicManip a) where<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;a + b = Arith Plus a b<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;a - b = Arith Minus a b<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;a * b = Arith Mul a b<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;negate a = Arith Mul (Number (-1)) a<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;abs a = error "abs is unimplemented"<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;signum _ = error "signum is unimplemented"<br></blockquote><blockquote type="cite"> &nbsp;&nbsp;&nbsp;fromInteger i = Number (fromInteger i)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Ok, so far so good. But the following example seems quite astounding to me:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">ghci&gt; (5 * 10 + 2)::SymbolicManip Int<br></blockquote><blockquote type="cite">Arith Plus (Arith Mul (Number 5) (Number 10)) (Number 2)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">The book says to notice that haskell "converted" 5 * 10 + 2 into a SymbolicManip. Indeed!<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">My understanding breaks down at this point. I suspect that it may be my weak grasp of the implications of lazy evaluation, and typeclasses generally. My (incorrect) intuition makes me think that the stuff inside the parentheses should be evaluated first, and then typed as a SymbolicManip. This would give the result Number 52. <br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">My question may be too vague to answer easily, but what I am hoping for is a bit of a narrative regarding how haskell knows that the pieces inside the parentheses are each of type SymbolicManip Int. Or something like that....<br></blockquote><br><font class="Apple-style-span" color="#000000"><font class="Apple-style-span" color="#144FAE"><br></font></font></div></blockquote><blockquote type="cite"><div>I'm working through the book as well (at least, when I'm not otherwise<br>occupied), so will take a stab at an answer to see if *I* understand<br>it properly.<br><br>This doesn't have anything to do with lazy evaluation, but with type<br>inferencing. The type of the entire expression is "SymbolicManip Int"<br>(SMI from now on) because - well, you said it is. Since the type of<br>the expression is SMI, the type of (X + 2) must be SMI, which means<br>the (+) function has to produce that result type, and the only<br>function that does that is the SMI instance of Num. Since it's two<br>arguments are of type SMI, the sub-expression (5 * 10) gets the same<br>treatment, and then all of the integers gets turned into an SMI using</div></blockquote><blockquote type="cite"><div>the function specified by fromInteger because they also have to be of<br>type SMI.<br><br></div></blockquote><br><div><div>Ok, thanks - very helpful to me. I think (maybe) I see why I thought lazy evaluation was involved, although I may still be reasoning badly.</div><div><br></div><div>I was perhaps reverting to C thinking, treating the type SymbolicManip Int as a type-cast rather than as a type, and assuming that it would be possible to evaluate (5 * 10 + 2) &nbsp;<i>first</i>&nbsp;(whatever the heck that might mean)&nbsp;and then convert it. I somehow imagined that evaluating the expression lazily might do something good - heaven knows what - in this respect.</div><div><br></div><div>My understanding now is that type inference is necessary (to arrive at an instance of Num) in order for (+) and (*) to have meaning, My notion of evaluating the expression&nbsp;<i>before</i>&nbsp;type inference is probably just silly, in that light.</div><div><br></div><div>I think I also see why the implicit wrapping of integer literals in fromInteger is essential. This is mentioned in RWH, and also by Brandon Allbery's response to my post, but I did not grasp it initially.</div><div><br></div><div>Thanks again.</div></div></div><div><br></div><div>Best,&nbsp;</div><div><br></div><div>- Jake -</div></body></html>