为什么是[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
呢?
为什么是[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
呢?
由于字符串是 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
使用字典顺序的列表的实例不一致。
免责声明:我对 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。
首先,你对“a”和“aa”是错误的:
Prelude> "a" < "aA" && "aA" < "aa"
True
“foo”之后的下一个字符串是什么?是“fop”吗?是“福阿”吗?是“foo\0”吗?