Reputation: 11963
Why is [Char]
an instance of Ord
, but not of Enum
?
Prelude> let succ_a = "a" ++ [minBound::Char]
Prelude> "a" < succ_a
True
Prelude> succ_a < "a "
True
Prelude> succ_a < succ_a ++ [minBound::Char]
True
I think there's no String between "a" and succ_a
- so why not succ "a" == succ_a
?
Upvotes: 5
Views: 744
Reputation: 139890
Since strings are lists in Haskell, you might as well ask why lists aren't in Enum
, since you wouldn't be able to write an instance for just strings without extensions. But that doesn't matter. The problem is that enumeration in lexicographical order isn't very useful, since you just keep appending the smallest character at the end indefinitely.
Using the alphabet a..z
for simplicity, lexicographical order just gives us repetitions of the first letter.
"", "a", "aa", "aaa", "aaaa", "aaaaa" ...
The more useful order for enumerating strings is by length. This way, we first get the empty string, then all the strings of length 1, then all of length 2, etc.
"", "a", "b", ... "z", "aa", "ba", ... "za", "ab", ... "zz", "aaa", "baa" ...
This is essentially the same as enumerating integers, with the digits reversed, so when you get to "zz"
you carry and get "aaa"
, just like how you get from 99 to 100.
However, this would be inconsistent with the Ord
instance for lists which uses the lexicographical ordering.
Upvotes: 17
Reputation: 5843
Disclaimer: I don't know much about Haskell.
However, it seems from http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Enum that an Enum has to support toEnum and fromEnum to convert from the enum type to Int and back again. How would this work for strings? If succ_a = "a" ++ [minBound::Char]
, then any Int maps onto a string "a" with some number of minBound::Char
's appended to it (or more realistically, any Int n
maps onto a list of size n
which contains only minBound::Char
). So, "b" would not map onto any Int.
Upvotes: 4
Reputation: 2437
First, you're wrong about "a" and "aa":
Prelude> "a" < "aA" && "aA" < "aa"
True
What's the next string after "foo"? Is it "fop"? Is it "fooa?" Is it "foo\0"?
Upvotes: 2