为什么[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
?
答案 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”吗?