@rzeta0 does this help?
[minBound .. maxBound] :: [Ordering]
[LT,EQ,GT]
@rzeta0 @jonocarroll I think it's mainly for use with collections.
Take a list of numbers, pick a number, annotate each item with the comparison to that number, sort the annotated list - the items would be in that lt/eq/gt order wrt. to pivot.
The same as subtracting the pivot, the numbers will be negative, then zeroes, then positive.
for me, even this example is a puzzle.
why would False precede True
my (limited) experience tells me they are concepts with neither being cardinally or ordinally different in nature
why would Orange precede Apple?
( I understand the causation being the definition in the library )
@rzeta0 @dpwiz succ gets the next value of an enum. The Bool enum is defined as False | True.
https://hackage.haskell.org/package/base-4.21.0.0/docs/Prelude.html#v:succ
succ = toEnum . (+ 1) . fromEnum
If you defined an enum
Fruit = Orange | Apple | Pear
then yes, you would expect that succ Orange = Apple
Enums are typically implemented as ints under the hood, so I don't find it surprising that they have an inherent order, but if you were thinking about them like dict keys then perhaps that's unexpected.
@rzeta0 @jonocarroll @dpwiz my guess is it has to do with how computers traditionally represented less-than, equal, and greater-than. For example in C the strcmp()
function does something similar, it returns -1, 0, or 1 for LT, EQ, and GT (respectively). Similarly, False is usually 0 and True is usually 1 (except in the Bourne Shell where it is ass-backwards).
The ordering of LT, EQ, and GT also makes sense mathematically, in my opinion. You can think of them as unit vectors indicating the direction of one point relative to another in some vector space.
@rzeta0 @jonocarroll I think this has roots in logic.
TLDR: There's a privileged element for "nothingness" and the rest are "something". So, for the types that map to some number it is natural to expect at least the 0th elements to align.
If you take numerical encoding of enums as an inductive type then there would be the "smallest" element - `Zero`, and the "next" element and you'd get the type `data N = Zero | Next N`. It can be used to encode all kinds of enums. But then, the same principle is used to encode e.g. lists: `data List a = Empty | Item a (List a)`.
So, why would the `False` go first then? Consider the function `len` that maps arbitrary lists to numbers: len Empty = Zero; len (Item next) = Next (len next).
The empty lists has no layers and so the number zero has no layers.
Recall my previous diatribe about multiple ways converging on the same outcome? Here we have another case of that. We can handwave the property being "has something". The lists have elements, the numbers have quantity, and the True is some bit being "on".
Exactly the same thing goes for the Maybe type, it's just more specific in what exactly it have got in there.
thanks for all the replies and your patience ! :)
why would the following be wrong?
data Bool = True | False
@jonocarroll @rzeta0 Collections are just example of doing things of least surprise. There is a web of concepts that are expected to behave similarly. If there are multiple ways to do the comparison, they ought to have same results since the underlying property is the same across all the implementations.
@dpwiz @rzeta0 I think the question is about the ordering of the enum itself, not the application to a collection. There needs to be some order of the values, and perhaps it's arbitrary, but LT, EQ, GT seems the most natural.
Similarly, and perhaps more enlightening:
ghci> succ False
True
ghci> pred True
False
because it's defined as
data Bool = False | True