4

为什么是[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呢?

4

3 回答 3

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使用字典顺序的列表的实例不一致。

于 2012-04-27T19:24:21.297 回答
4

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

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

于 2012-04-27T18:47:03.980 回答
2

首先,你对“a”和“aa”是错误的:

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

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

于 2012-04-27T18:24:12.640 回答