Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Haskell-cafe] Learn You a Haskell for Great Good - a few doubts

72 views
Skip to first unread message

Karthick Gururaj

unread,
Mar 3, 2011, 1:17:05 AM3/3/11
to haskel...@haskell.org
Hello,

I'm learning Haskell from the extremely well written (and well
illustrated as well!) tutorial - http://learnyouahaskell.com/chapters.
I have couple of questions from my readings so far.

In "typeclasses - 101"
(http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101),
there is a paragraph that reads:
Enum members are sequentially ordered types - they can be enumerated.
The main advantage of the Enum typeclass is that we can use its types
in list ranges. They also have defined successors and predecesors,
which you can get with the succ and pred functions. Types in this
class: (), Bool, Char, Ordering, Int, Integer, Float and Double.

What is the "()" type? Does it refer to a tuple? How can tuple be
ordered, let alone be enum'd? I tried:
Prelude> take 10 [(1,1) ..]
<interactive>:1:8:
    No instance for (Enum (t, t1))
      arising from the arithmetic sequence `(1, 1) .. '
                   at <interactive>:1:8-17
    Possible fix: add an instance declaration for (Enum (t, t1))
    In the second argument of `take', namely `[(1, 1) .. ]'
    In the expression: take 10 [(1, 1) .. ]
    In the definition of `it': it = take 10 [(1, 1) .. ]

This is expected and is logical.

But, surprise:
Prelude> (1,1) > (1,2)
False
Prelude> (2,2) > (1,1)
True
Prelude> (1,2) > (2,1)
False
Prelude> (1,2) < (2,1)
True

So tuples are in "Ord" type class atleast. What is the ordering logic?

Another question, on the curried functions - specifically for infix
functions. Suppose I need a function that takes an argument and adds
five to it. I can do:
Prelude> let addFive = (+) 5
Prelude> addFive 4
9

The paragraph: "Infix functions can also be partially applied by using
sections. To section an infix function, simply surround it with
parentheses and only supply a parameter on one side. That creates a
function that takes one parameter and then applies it to the side
that's missing an operand": describes a different syntax. I tried that
as well:

Prelude> let addFive' = (+5)
Prelude> addFive' 3
8

Ok. Works. But on a non-commutative operation like division, we get:
Prelude> let x = (/) 20.0
Prelude> x 10
2.0
Prelude> let y = (/20.0)
Prelude> y 10
0.5

So a curried infix operator fixes the first argument and a "sectioned
infix" operator fixes the second argument?

Regards,
Karthick

_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Chris Smith

unread,
Mar 3, 2011, 1:23:38 AM3/3/11
to Karthick Gururaj, haskel...@haskell.org
On Thu, 2011-03-03 at 11:39 +0530, Karthick Gururaj wrote:
> What is the "()" type? Does it refer to a tuple? How can tuple be
> ordered, let alone be enum'd? I tried:

The () type is pronounced "unit". It is a type with only 1 value, also
called () and pronounced "unit". Since it only has one possible value,
it conveys no information at all, and is sometimes used in situations
analogous to C's 'void' keyword.

Okay, actually that was a little bit of a lie; () has two "values": ()
and bottom. Bottom is the "value" that corresponds to the program
hanging in an infinite loop or dying with an error message. But if you
have an actual, honest-to-goodness value that's not bottom, it has to be
().

> But, surprise:
> Prelude> (1,1) > (1,2)
> False
> Prelude> (2,2) > (1,1)
> True
> Prelude> (1,2) > (2,1)
> False
> Prelude> (1,2) < (2,1)
> True

Okay, so this is no longer Enum, but just Ord. The ordering defined in
the Ord instance for tuples is the normal lexicographic order: the
comparison between the first elements dominates; but if the first
elements coincide, then the second are compared instead. For larger
tuple types, the same pattern continues.

Think of it like organizing words in alphabetical order, where here you
know the words all have the same number of letters.

> Ok. Works. But on a non-commutative operation like division, we get:
> Prelude> let x = (/) 20.0
> Prelude> x 10
> 2.0
> Prelude> let y = (/20.0)
> Prelude> y 10
> 0.5
>
> So a curried infix operator fixes the first argument and a "sectioned
> infix" operator fixes the second argument?

Sections can be either left sections or right sections, so you can pick
which argument is provided.

Prelude> let y = (/ 20.0)
Prelude> y 10
0.5
Prelude> let y = (20.0 /)
Prelude> y 10
2.0

Hope that helps,

--
Chris Smith

Karthick Gururaj

unread,
Mar 3, 2011, 2:14:11 AM3/3/11
to Chris Smith, haskel...@haskell.org
On Thu, Mar 3, 2011 at 11:48 AM, Chris Smith <cds...@gmail.com> wrote:
> On Thu, 2011-03-03 at 11:39 +0530, Karthick Gururaj wrote:
>> What is the "()" type? Does it refer to a tuple? How can tuple be
>> ordered, let alone be enum'd? I tried:
>
> The () type is pronounced "unit".  It is a type with only 1 value, also
> called () and pronounced "unit".  Since it only has one possible value,
> it conveys no information at all, and is sometimes used in situations
> analogous to C's 'void' keyword.
>
> Okay, actually that was a little bit of a lie; () has two "values": ()
> and bottom.  Bottom is the "value" that corresponds to the program
> hanging in an infinite loop or dying with an error message.  But if you
> have an actual, honest-to-goodness value that's not bottom, it has to be
> ().
Thanks - is this the same "unit" that accompanies IO in "IO ()" ? In
any case, my question is answered since it is not a tuple.

Thanks, it does!

Ivan Lazar Miljenovic

unread,
Mar 3, 2011, 2:26:24 AM3/3/11
to Karthick Gururaj, haskel...@haskell.org
On 3 March 2011 17:59, Karthick Gururaj <karthick...@gmail.com> wrote:
> On Thu, Mar 3, 2011 at 11:48 AM, Chris Smith <cds...@gmail.com> wrote:
>> On Thu, 2011-03-03 at 11:39 +0530, Karthick Gururaj wrote:
>>> What is the "()" type? Does it refer to a tuple? How can tuple be
>>> ordered, let alone be enum'd? I tried:
>>
>> The () type is pronounced "unit".  It is a type with only 1 value, also
>> called () and pronounced "unit".  Since it only has one possible value,
>> it conveys no information at all, and is sometimes used in situations
>> analogous to C's 'void' keyword.
>>
>> Okay, actually that was a little bit of a lie; () has two "values": ()
>> and bottom.  Bottom is the "value" that corresponds to the program
>> hanging in an infinite loop or dying with an error message.  But if you
>> have an actual, honest-to-goodness value that's not bottom, it has to be
>> ().
> Thanks - is this the same "unit" that accompanies IO in "IO ()" ? In
> any case, my question is answered since it is not a tuple.

Yes.

--
Ivan Lazar Miljenovic
Ivan.Mi...@gmail.com
IvanMiljenovic.wordpress.com

Antti-Juhani Kaijanaho

unread,
Mar 3, 2011, 3:04:03 AM3/3/11
to haskel...@haskell.org
On Thu, Mar 03, 2011 at 12:29:44PM +0530, Karthick Gururaj wrote:
> Thanks - is this the same "unit" that accompanies IO in "IO ()" ? In
> any case, my question is answered since it is not a tuple.

It can be viewed as the trivial 0-tuple.

--
Antti-Juhani Kaijanaho, Jyväskylä, Finland
http://antti-juhani.kaijanaho.fi/newblog/
http://www.flickr.com/photos/antti-juhani/

Paul Sujkov

unread,
Mar 3, 2011, 9:36:35 AM3/3/11
to Karthick Gururaj, haskel...@haskell.org
Hi,

you can always check the types using GHCi prompt:

*Prelude> :i (,)
data (,) a b = (,) a b -- Defined in GHC.Tuple
instance (Bounded a, Bounded b) => Bounded (a, b)
-- Defined in GHC.Enum
instance (Eq a, Eq b) => Eq (a, b) -- Defined in Data.Tuple
instance Functor ((,) a) -- Defined in Control.Monad.Instances
instance (Ord a, Ord b) => Ord (a, b) -- Defined in Data.Tuple
instance (Read a, Read b) => Read (a, b) -- Defined in GHC.Read
instance (Show a, Show b) => Show (a, b) -- Defined in GHC.Show

that's for a tuple. You can see that tuple has an instance for the Ord
class.

*Prelude> :i ()
data () = () -- Defined in GHC.Unit
instance Bounded () -- Defined in GHC.Enum
instance Enum () -- Defined in GHC.Enum
instance Eq () -- Defined in Data.Tuple
instance Ord () -- Defined in Data.Tuple
instance Read () -- Defined in GHC.Read
instance Show () -- Defined in GHC.Show

and that's for a unit type.

--
Regards, Paul Sujkov

Karthick Gururaj

unread,
Mar 3, 2011, 9:55:08 AM3/3/11
to Paul Sujkov, haskel...@haskell.org
On Thu, Mar 3, 2011 at 8:00 PM, Paul Sujkov <psu...@gmail.com> wrote:
> Hi,
> you can always check the types using GHCi prompt:
> *Prelude> :i (,)
> data (,) a b = (,) a b -- Defined in GHC.Tuple
> instance (Bounded a, Bounded b) => Bounded (a, b)
>   -- Defined in GHC.Enum
> instance (Eq a, Eq b) => Eq (a, b) -- Defined in Data.Tuple
> instance Functor ((,) a) -- Defined in Control.Monad.Instances
> instance (Ord a, Ord b) => Ord (a, b) -- Defined in Data.Tuple
> instance (Read a, Read b) => Read (a, b) -- Defined in GHC.Read
> instance (Show a, Show b) => Show (a, b) -- Defined in GHC.Show
> that's for a tuple. You can see that tuple has an instance for the Ord
> class.
> *Prelude> :i ()
> data () = () -- Defined in GHC.Unit
> instance Bounded () -- Defined in GHC.Enum
> instance Enum () -- Defined in GHC.Enum
> instance Eq () -- Defined in Data.Tuple
> instance Ord () -- Defined in Data.Tuple
> instance Read () -- Defined in GHC.Read
> instance Show () -- Defined in GHC.Show
> and that's for a unit type.
> [snip]
Ah, thanks! I didn't know about :i, tried only :t () which didn't give
very interesting information.

Alexander Solla

unread,
Mar 3, 2011, 4:05:23 PM3/3/11
to Karthick Gururaj, Haskell Cafe
On Wed, Mar 2, 2011 at 10:09 PM, Karthick Gururaj <
karthick...@gmail.com> wrote:

> Hello,
>
> I'm learning Haskell from the extremely well written (and well
> illustrated as well!) tutorial - http://learnyouahaskell.com/chapters.
> I have couple of questions from my readings so far.
>
> In "typeclasses - 101"
> (http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101),
> there is a paragraph that reads:
> Enum members are sequentially ordered types - they can be enumerated.
> The main advantage of the Enum typeclass is that we can use its types
> in list ranges. They also have defined successors and predecesors,
> which you can get with the succ and pred functions. Types in this
> class: (), Bool, Char, Ordering, Int, Integer, Float and Double.
>
> What is the "()" type? Does it refer to a tuple? How can tuple be
> ordered, let alone be enum'd?
>

Any set can be put into an order. That's the well-ordering principle.
Basically, the most natural order for pairs is the lexicographical order.
There are instances of the form:

instance (Ord a, Ord b) => Ord (a,b)

in GHC.Enum (if you're using GHC). You can also create Enum instances for
pairs, but at least one of the "sides" must be bounded. Otherwise, the
enumeration will have an uncomputable order-type (something like the order
type of the rationals). Check out http://en.wikipedia.org/wiki/Order_type if
you're interested in what all that "order type" stuff means.

I wrote an instance for this very purpose the other day:


-- An intuitive way to think about this is in terms of tables. Given
datatypes
--
-- @
-- data X = A | B | C | D deriving ('Bounded', 'Enum', 'Eq', 'Ord', 'Show')
-- data Y = E | F | G deriving ('Bounded', 'Enum', 'Eq', 'Ord', 'Show')
-- @
--
-- we can form the table
--
-- @
-- (A, E) (A, F) (A, G)
-- (B, E) (B, F) (B, G)
-- (C, E) (C, F) (C, G)
-- (D, E) (D, F) (D, G)
-- @
--
-- in a natural lexicographical order. We simply require that there be a
finite
-- number of columns, and allow an unbounded number of rows (in so far as
the
-- lazy evaluation mechanism allows them). In even more practical terms, we
require
-- a finite number of columns because we use that number to perform
arithmetic.

instance ( Bounded b
, Enum a
, Enum b
) => Enum (a, b) where
toEnum k = let n = 1 + fromEnum (maxBound :: b) -- Enums are 0
indexed, but we want to
a = toEnum ((k `div` n)) -- divide by
the number of elements in a row to find the row and
b = toEnum ((k `mod` n)) -- get the
remainder to find the column.
in (a,b)

fromEnum (a, b) = let n = 1 + fromEnum (maxBound :: b)
i = fromEnum a
j = fromEnum b
in (i*n + j)

-- | This instance of 'Enum' is defined in terms of the previous instance.
We
-- use the natural equivalence of the types @(a,b,c)@ and @(a,(b,c))@ and
use
-- the previous definition. Again, notice that all elements but the first
must
-- be bounded.
instance ( Bounded b
, Bounded c
, Enum a
, Enum b
, Enum c
) => Enum (a, b, c) where
fromEnum (a, b, c) = fromEnum (a, (b,c))
toEnum k = let (a, (b, c)) = toEnum k
in (a, b, c)


> So tuples are in "Ord" type class atleast. What is the ordering logic?
>
>

Lexicographical. Dictionary order.

Another question, on the curried functions - specifically for infix
> functions. Suppose I need a function that takes an argument and adds
> five to it. I can do:
> Prelude> let addFive = (+) 5
> Prelude> addFive 4
> 9
>
> The paragraph: "Infix functions can also be partially applied by using
> sections. To section an infix function, simply surround it with
> parentheses and only supply a parameter on one side. That creates a
> function that takes one parameter and then applies it to the side
> that's missing an operand": describes a different syntax. I tried that
> as well:
>
> Prelude> let addFive' = (+5)
> Prelude> addFive' 3
> 8
>
> Ok. Works. But on a non-commutative operation like division, we get:
> Prelude> let x = (/) 20.0
> Prelude> x 10
> 2.0
> Prelude> let y = (/20.0)
> Prelude> y 10
> 0.5
>
> So a curried infix operator fixes the first argument and a "sectioned
> infix" operator fixes the second argument?
>

I guess, except you can section infix operators the other way:

> let twentyover = (20 /)
> twentyover 5
4.0

Richard O'Keefe

unread,
Mar 3, 2011, 5:03:47 PM3/3/11
to Karthick Gururaj, haskel...@haskell.org
By the way, tuples *can* be members of Enum if you make them so.
Try

instance (Enum a, Enum b, Bounded b) => Enum (a,b)
where
toEnum n = (a, b)
where a = toEnum (n `div` s)
b = toEnum (n `mod` s)
p = fromEnum (minBound `asTypeOf` b)
q = fromEnum (maxBound `asTypeOf` b)
s = q - p + 1
fromEnum (a, b) = fromEnum a * s + fromEnum b
where p = fromEnum (minBound `asTypeOf` b)
q = fromEnum (maxBound `asTypeOf` b)
s = q - p + 1


data T1 = A | B | C deriving (Enum, Eq, Bounded, Show)
data T2 = D | E | F deriving (Enum, Eq, Bounded, Show)

t1 = [(A,D) .. (B,F)]

I can't think of an approach that doesn't require all but one of
the tuple elements to have Bounded types. There are of course
all sorts of ways to enumerate tuples; this one is compatible
with the Ord instance.

Alexander Solla

unread,
Mar 3, 2011, 5:31:23 PM3/3/11
to Haskell Cafe
On Thu, Mar 3, 2011 at 1:58 PM, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:

>
> I can't think of an approach that doesn't require all but one of
> the tuple elements to have Bounded types.


It's not possible. Such an enumeration could potentially have an
uncomputable order-type, possibly equal to the order-type of the rationals.
(In other words, there could be countably infinitely many elements between
any two elements)

It's possible to define a computational system where you can do arithmetic
on countable ordinals, but it has the expressive power of Turing machines
with oracles (where an oracle is a thing that correctly guesses the "right"
answer for a computation that does not halt in finite time (consider a
sequence approaching pi as a limit). We can re-interpret the oracle's
guess as passing to a limit ordinal. In any case, TMs+ oracles are strictly
stronger than just TMs.

Markus

unread,
Mar 3, 2011, 9:35:10 PM3/3/11
to Daniel Fischer, haskel...@haskell.org
What about having the order by diagonals, like:

0 1 3
2 4
5

and have none of the pair be bounded?

--
Markus Läll

On 4 Mar 2011, at 01:10, Daniel Fischer <daniel.i...@googlemail.com
> wrote:

> On Thursday 03 March 2011 23:25:48, Alexander Solla wrote:
>> On Thu, Mar 3, 2011 at 1:58 PM, Richard O'Keefe <o...@cs.otago.ac.nz>
> wrote:
>>> I can't think of an approach that doesn't require all but one of
>>> the tuple elements to have Bounded types.
>>
>> It's not possible.
>

> Meaning: It's not possible while respecting the order.
> Ignoring the order, it's of course possible (finite products of
> countable
> sets are countable).

Karthick Gururaj

unread,
Mar 3, 2011, 11:54:45 PM3/3/11
to haskel...@haskell.org
There are so many responses, that I do not know where to start..

I'm top-posting since that seems best here, let me know if there are
group guidelines against that.

Some clarifications in order on my original post:
a. I ASSUMED that '()' refers to tuples, where we have atleast a pair.
This is from my Haskell ignorance, so let us forget that for now.
b. Also, when I said: tuples can not be ordered, let alone be enum'd -
I meant: there is no reasonable way of ordering tuples, let alone enum
them.

That does not mean we can't define them:
1. (a,b) > (c,d) if a>c
2. (a,b) > (c,d) if b>d
3. (a,b) > (c,d) if a^2 + b^2 > c^2 + d^2
4. (a,b) > (c,d) if a*b > c*d

If we can imagine (a,b) as a point in the xy plane, (1) defines
ordering based on which point is "more to the right of y axis", (2)
based on "which point is more above x axis", (3) on "which point is
farther from origin" and (4) on "which rectangle made of origin and
the point as diagonally opposite vertices has more area". Which of
these is a reasonable definition? The set of complex numbers do not
have a "default" ordering, due to this very issue.

For enumerating them, we *can* go along the diagonal as suggested. But
why that and not something else? By the way - enumerating them along
the diagonal introduces a new ordering between tuples.

When we do not have a "reasonable" way of ordering, I'd argue to not
have anything at all - let the user decide based on his/her
application of the tuple.

As a side note, the cardinality of rational numbers is the same as
those of integers - so both are "equally" infinite.

Regards,
Karthick


On Fri, Mar 4, 2011 at 8:42 AM, Daniel Fischer
<daniel.i...@googlemail.com> wrote:


> On Friday 04 March 2011 03:24:34, Markus wrote:
>> What about having the order by diagonals, like:
>>
>> 0 1 3
>> 2 4
>> 5
>>
>> and have none of the pair be bounded?
>>
>

> I tacitly assumed product order (lexicographic order).

Richard O'Keefe

unread,
Mar 4, 2011, 12:17:24 AM3/4/11
to Karthick Gururaj, haskel...@haskell.org

On 4/03/2011, at 5:49 PM, Karthick Gururaj wrote:
> I meant: there is no reasonable way of ordering tuples, let alone enum
> them.

There are several reasonable ways to order tuples.


>
> That does not mean we can't define them:
> 1. (a,b) > (c,d) if a>c

Not really reasonable because it isn't compatible with equality.


> 2. (a,b) > (c,d) if b>d
> 3. (a,b) > (c,d) if a^2 + b^2 > c^2 + d^2
> 4. (a,b) > (c,d) if a*b > c*d

Ord has to be compatible with Eq, and none of these are.
Lexicographic ordering is in wide use and fully compatible
with Eq.


> Which of
> these is a reasonable definition?

> The set of complex numbers do not
> have a "default" ordering, due to this very issue.

No, that's for another reason. The complex numbers don't have
a standard ordering because when you have a ring or field and
you add an ordering, you want the two to be compatible, and
there is no total order for the complex numbers that fits in
the way required.


>
> When we do not have a "reasonable" way of ordering, I'd argue to not
> have anything at all

There is nothing unreasonable about lexicographic order.
It makes an excellent default.


>
>
> As a side note, the cardinality of rational numbers is the same as
> those of integers - so both are "equally" infinite.

Ah, here we come across the distinction between cardinals and
ordinals. Two sets can have the same cardinality but not be
the same order type. (Add 1 to the first infinite cardinal
and you get the same cardinal back; add 1 to the first infinite
ordinal and you don't get the same ordinal back.)

wren ng thornton

unread,
Mar 4, 2011, 1:19:49 AM3/4/11
to haskel...@haskell.org
On 3/3/11 2:58 AM, Antti-Juhani Kaijanaho wrote:
> On Thu, Mar 03, 2011 at 12:29:44PM +0530, Karthick Gururaj wrote:
>> Thanks - is this the same "unit" that accompanies IO in "IO ()" ? In
>> any case, my question is answered since it is not a tuple.
>
> It can be viewed as the trivial 0-tuple.

Except that this is problematic since Haskell doesn't have 1-tuples
(which would be distinct from plain values in that they have an extra
bottom).

In an idealized world, yes, unit can be thought of as the nullary
product which serves as left- and right-identity for the product
bifunctor. Unfortunately, Haskell's tuples aren't quite products.[1]


[1] To be fair, a lot of thought went into choosing for them to be the
way they are. The way they are generally matches the semantics we
desire, but this is one of the places where they don't. The only way to
"fix" this is to have two different product types, which is problematic
for the obvious reasons.

--
Live well,
~wren

Karthick Gururaj

unread,
Mar 4, 2011, 4:54:43 AM3/4/11
to haskel...@haskell.org
On Fri, Mar 4, 2011 at 10:42 AM, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:
>
> On 4/03/2011, at 5:49 PM, Karthick Gururaj wrote:
>> I meant: there is no reasonable way of ordering tuples, let alone enum
>> them.
>
> There are several reasonable ways to order tuples.
>>
>> That does not mean we can't define them:
>> 1. (a,b) > (c,d) if a>c
>
> Not really reasonable because it isn't compatible with equality.
>> 2. (a,b) > (c,d) if b>d
>> 3. (a,b) > (c,d) if a^2 + b^2 > c^2 + d^2
>> 4. (a,b) > (c,d) if a*b > c*d
>
> Ord has to be compatible with Eq, and none of these are.
Hmm.. not true. Can you explain what do you mean by "compatibility"?

One of the following, and exactly one, must always hold, on a ordered
set (is this what you mean by "compatibility"?), for any arbitrary
legal selection of a, b, c and d.
a. (a, b) EQ (c, d)
b. (a, b) LT (c, d)
c. (a, b) GT (c, d)

All the definitions above are compatible in this sense.

> Lexicographic ordering is in wide use and fully compatible
> with Eq.
>> Which of
>> these is a reasonable definition?
>
>> The set of complex numbers do not
>> have a "default" ordering, due to this very issue.
>
> No, that's for another reason.  The complex numbers don't have
> a standard ordering because when you have a ring or field and
> you add an ordering, you want the two to be compatible, and
> there is no total order for the complex numbers that fits in
> the way required.
>>
>> When we do not have a "reasonable" way of ordering, I'd argue to not
>> have anything at all
>
> There is nothing unreasonable about lexicographic order.
> It makes an excellent default.

Ok - at this stage, I'll just take your word for it. I'm not able to
still appreciate the choice of the default ordering order, but I need
to wait until I get to see/develop some real code.

>>
>>
>> As a side note, the cardinality of rational numbers is the same as
>> those of integers - so both are "equally" infinite.
>
> Ah, here we come across the distinction between cardinals and
> ordinals.  Two sets can have the same cardinality but not be
> the same order type.  (Add 1 to the first infinite cardinal
> and you get the same cardinal back; add 1 to the first infinite
> ordinal and you don't get the same ordinal back.)

:) Ok. The original point was whether there is a reasonable way to
enumerate a tuple, I guess there is none.

Chris Smith

unread,
Mar 4, 2011, 10:43:59 AM3/4/11
to Karthick Gururaj, haskel...@haskell.org
On Mar 4, 2011 2:49 AM, "Karthick Gururaj" <karthick...@gmail.com>
wrote:

> > Ord has to be compatible with Eq, and none of these are.
> Hmm.. not true. Can you explain what do you mean by "compatibility"?

Compatibility would mean that x == y if and only if compare x y == EQ. This
is not a restricrion enforced by the type system, but it is something that I
would think ought to be true (though it is not,for example, for the IEEE
floating point types; I personally consider that a bug and believe the IEEE
notions of comparison ought to be exposed in a different set of operations
rather than instances of Ord and Eq). In this sense it is much like the
monad laws. So whether it has to be true depends on what you mean by "has
to be".

> Ok - at this stage, I'll just take your word for it. I'm not able to
> still appreciate the choice of the default ordering order, but I need
> to wait until I get to see/develop some real code.

The most common use of Ord in real code, to be honest, is to use the value
in some data structure like Data.Set.Set or Data.Map.Map, which requires Ord
instances. For this purpose, any Ord instance that is compatible with Eq
will do fine.

--
Chris

Ozgur Akgun

unread,
Mar 4, 2011, 10:55:32 AM3/4/11
to Karthick Gururaj, haskel...@haskell.org
On 4 March 2011 09:47, Karthick Gururaj <karthick...@gmail.com> wrote:

> I'm not able to still appreciate the choice of the default ordering order,
>

I don't know if this will help you appreciate the default or not, but just
to say this default is concordant with the auto-derived Ord instances.

data Tuple3 a b c = Tuple3 a b c
deriving (Eq,Ord,Show)

ghci> sort [Tuple3 1 2 4, Tuple3 1 2 3, Tuple3 2 1 1, Tuple3 1 3 5]
[Tuple3 1 2 3,Tuple3 1 2 4,Tuple3 1 3 5,Tuple3 2 1 1]

ghci> sort [(1,2,4), (1,2,3), (2,1,1), (1,3,5)]
[(1,2,3),(1,2,4),(1,3,5),(2,1,1)]

No surprises here. Just another place where we have the lexicographic
ordering by default.

HTH,

--
Ozgur Akgun

Max Rabkin

unread,
Mar 4, 2011, 10:57:17 AM3/4/11
to Chris Smith, haskel...@haskell.org
On Fri, Mar 4, 2011 at 17:37, Chris Smith <cds...@gmail.com> wrote:
> The most common use of Ord in real code, to be honest, is to use the value
> in some data structure like Data.Set.Set or Data.Map.Map, which requires Ord
> instances.  For this purpose, any Ord instance that is compatible with Eq
> will do fine.

It's true that you can build valid Maps and Sets with any valid
instance of Ord that defines a total order that is consistent with Eq,
and lookup, membership testing and insert will work. However, there
are operations on Maps and Sets which make the order visible to the
caller: min, max, splits, folds, etc.

--Max

Markus Läll

unread,
Mar 4, 2011, 11:51:34 AM3/4/11
to Daniel Fischer, alex....@gmail.com, haskel...@haskell.org
Sorry, I didn't mean to answer you in particular. I meant to say that for
tuples you could (I think) have an enumeration over them without requiring
any component be bounded.

An example of type (Integer, Integer) you would have:

[(0,0) ..] = [(0,0) (0,1) (1,0) (0,2) (1,1) (2,0) ... ]

where the order can be visualized by taking diagonals of a table starting
from the upper left:

0 1 2 ..
0 (0,0) (0,1) (0,2)
1 (1,0) (1,1) (1,2)
2 (2,0) (2,1) (2,2)
.

Would this also have an uncomputable order type? At least for comparing
tuples you'd just:

lt :: (Integer,Integer) -> (Integer,Integer) -> Bool
(a,b) `lt` (c,d) = let
sum1 = (a + b)
sum2 = (c + d)
in if sum1 == sum2
then a < c
else sum1 < sum2


Implementing fromEnum looks like a bit harder problem..


--
Markus Läll


On Fri, Mar 4, 2011 at 5:12 AM, Daniel Fischer <
daniel.i...@googlemail.com> wrote:
>
> On Friday 04 March 2011 03:24:34, Markus wrote:

> > What about having the order by diagonals, like:
> >
> > 0 1 3
> > 2 4
> > 5
> >
> > and have none of the pair be bounded?
> >
>

0 new messages