为什么String不是枚举?

时间:2012-04-27 18:22:02

标签: haskell

为什么[Char]Ord的实例,而不是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

我认为“a”和succ_a之间没有字符串 - 所以为什么不succ "a" == succ_a

3 个答案:

答案 0 :(得分:16)

由于字符串是Haskell中的列表,因此您可能会问为什么列表不在Enum中,因为您无法为没有扩展名的字符串编写实例。但那没关系。问题是,字典顺序中的枚举不是很有用,因为你只是无限期地在最后追加最小的字符。

为简单起见,使用字母a..z,词典顺序只是让我们重复第一个字母。

"", "a", "aa", "aaa", "aaaa", "aaaaa" ...

枚举字符串的更有用的顺序是长度。这样,我们首先得到空字符串,然后是长度为1的所有字符串,然后是长度为2的所有字符串,等等。

"", "a", "b", ... "z", "aa", "ba", ... "za", "ab", ... "zz", "aaa", "baa" ...

这与枚举整数基本相同,数字相反,所以当你到达"zz"时,你带着"aaa",就像你从99到100那样。

但是,这与使用词典排序的列表的Ord实例不一致。

答案 1 :(得分:4)

免责声明:我对Haskell了解不多。

然而,似乎从http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Enum开始,Enum必须支持toEnum和fromEnum才能从枚举类型转换为Int并再返回。这对字符串有什么作用?如果succ_a = "a" ++ [minBound::Char],则任何Int映射到字符串“a”,其中附加了一些minBound::Char(或者更实际地,任何Int n映射到大小列表{ {1}}仅包含n)。因此,“b”不会映射到任何Int。

答案 2 :(得分:2)

首先,你对“a”和“aa”错了:

Prelude> "a" < "aA" && "aA" < "aa"
True

“foo”之后的下一个字符串是什么?是“fop”吗?是“fooa?”是“foo \ 0”吗?