gcbenison
gcbenison

Reputation: 11963

Why isn't a String an Enum?

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

Answers (3)

hammar
hammar

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

Ord
Ord

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

Venge
Venge

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

Related Questions