<font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br><br></font><div class="gmail_quote"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">On Wed, Mar 2, 2011 at 10:09 PM, Karthick Gururaj <span dir="ltr">&lt;<a href="mailto:karthick.gururaj@gmail.com">karthick.gururaj@gmail.com</a>&gt;</span> wrote:<br>
</font><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">Hello,<br>
<br>
I&#39;m learning Haskell from the extremely well written (and well<br>
illustrated as well!) tutorial - <a href="http://learnyouahaskell.com/chapters" target="_blank">http://learnyouahaskell.com/chapters</a>.<br>
I have couple of questions from my readings so far.<br>
<br>
In &quot;typeclasses - 101&quot;<br>
(<a href="http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101" target="_blank">http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101</a>),<br>
there is a paragraph that reads:<br>
Enum members are sequentially ordered types - they can be enumerated.<br>
The main advantage of the Enum typeclass is that we can use its types<br>
in list ranges. They also have defined successors and predecesors,<br>
which you can get with the succ and pred functions. Types in this<br>
class: (), Bool, Char, Ordering, Int, Integer, Float and Double.<br>
<br>
What is the &quot;()&quot; type? Does it refer to a tuple? How can tuple be<br>
ordered, let alone be enum&#39;d?<br></font></blockquote><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">Any set can be put into an order.  That&#39;s the well-ordering principle.  Basically, the most natural order for pairs is the lexicographical order.  There are instances of the form:</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 (Ord a, Ord b) =&gt; Ord (a,b)</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">in GHC.Enum (if you&#39;re using GHC).  You can also create Enum instances for pairs, but at least one of the &quot;sides&quot; must be bounded.  Otherwise, the enumeration will have an uncomputable order-type (something like the order type of the rationals). Check out <a href="http://en.wikipedia.org/wiki/Order_type">http://en.wikipedia.org/wiki/Order_type</a> if you&#39;re interested in what all that &quot;order type&quot; stuff means.</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">I wrote  an instance for this very purpose the other day:</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"><br></font></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- An intuitive way to think about this is in terms of tables. Given datatypes</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">--</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- @</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- data X = A | B | C | D deriving (&#39;Bounded&#39;, &#39;Enum&#39;, &#39;Eq&#39;, &#39;Ord&#39;, &#39;Show&#39;)</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- data Y = E | F | G     deriving (&#39;Bounded&#39;, &#39;Enum&#39;, &#39;Eq&#39;, &#39;Ord&#39;, &#39;Show&#39;)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- @</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">--</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- we can form the table</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">--</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- @</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- (A, E)   (A, F)   (A, G)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- (B, E)   (B, F)   (B, G)</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- (C, E)   (C, F)   (C, G)</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- (D, E)   (D, F)   (D, G)</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- @</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">--</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- in a natural lexicographical order.  We simply require that there be a finite</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- number of columns, and allow an unbounded number of rows (in so far as the</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- lazy evaluation mechanism allows them).  In even more practical terms, we require</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- a finite number of columns because we use that number to perform arithmetic.</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 ( Bounded b</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         , Enum a</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         , Enum b</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         ) =&gt; Enum (a, b) where</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">              toEnum k = let n = 1 + fromEnum (maxBound :: b) -- Enums are 0 indexed, but we want to</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                             a = toEnum ((k `div` n))         -- divide by the number of elements in a row to find the row and</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                             b = toEnum ((k `mod` n))         -- get the remainder to find the column.</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                          in (a,b) </font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">              </font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">              fromEnum (a, b) = let n = 1 + fromEnum (maxBound :: b)</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                                    i = fromEnum a</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                                    j = fromEnum b</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                                 in (i*n + j)</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">-- | This instance of &#39;Enum&#39; is defined in terms of the previous instance.  We</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- use the natural equivalence of the types @(a,b,c)@ and @(a,(b,c))@ and use</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- the previous definition.  Again, notice that all elements but the first must</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">-- be bounded.</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">instance ( Bounded b</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         , Bounded c</font></div><div>
<font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         , Enum a</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         , Enum b</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         , Enum c</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">         ) =&gt; Enum (a, b, c) where</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                   fromEnum (a, b, c) = fromEnum (a, (b,c))</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                   toEnum k = let (a, (b, c)) = toEnum k</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                               in (a, b,  c)</font></div>
<div>                                                       </div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"> </font></div></div><div><br></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<br>
So tuples are in &quot;Ord&quot; type class atleast. What is the ordering logic?<br>
<br></blockquote><div><br></div><div>Lexicographical.  Dictionary order. </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Another question, on the curried functions - specifically for infix<br>
functions. Suppose I need a function that takes an argument and adds<br>
five to it. I can do:<br>
Prelude&gt; let addFive = (+) 5<br>
Prelude&gt; addFive 4<br>
9<br>
<br>
The paragraph: &quot;Infix functions can also be partially applied by using<br>
sections. To section an infix function, simply surround it with<br>
parentheses and only supply a parameter on one side. That creates a<br>
function that takes one parameter and then applies it to the side<br>
that&#39;s missing an operand&quot;: describes a different syntax. I tried that<br>
as well:<br>
<br>
Prelude&gt; let addFive&#39; = (+5)<br>
Prelude&gt; addFive&#39; 3<br>
8<br>
<br>
Ok. Works. But on a non-commutative operation like division, we get:<br>
Prelude&gt; let x = (/) 20.0<br>
Prelude&gt; x 10<br>
2.0<br>
Prelude&gt; let y = (/20.0)<br>
Prelude&gt; y 10<br>
0.5<br>
<br>
So a curried infix operator fixes the first argument and a &quot;sectioned<br>
infix&quot; operator fixes the second argument?<br></blockquote><div><br></div><div>I guess, except you can section infix operators the other way:</div><div><br></div><div>&gt; let twentyover = (20 /)</div><div><div>&gt; twentyover 5</div>
<div>4.0</div></div></div>