【问题标题】:Haskell Char and unicode surrogatesHaskell Char 和 unicode 代理
【发布时间】:2014-02-03 05:04:41
【问题描述】:

我正在玩弄字符串,发现 Haskell(正确地)不允许高于 Unicode 代码点 0x10ffff 的字符(即,如果尝试使用超出此限制的内容,则会出现类似序列超出范围的错误)。出于好奇,我玩弄了 Unicode 代理一半(0xd800 到 0xdfff)——无效的 Unicode 代码点,并发现它们似乎是允许的。我很好奇为什么会这样。仅仅是因为作为有界项意味着只定义最大值和最小值吗?

【问题讨论】:

    标签: haskell unicode


    【解决方案1】:

    禁止代理代码单元确实会使Char 成为更正确的Unicode 代码点类型。报告称 Char 是“其值代表 Unicode 字符的枚举”,因此这可能应该被视为 GHC 错误。

    没有“有界项”的具体概念,但它需要在各个地方进行额外检查(例如,现在chr 只需要进行一次比较以检查其参数是否有效)并可能进行一些事情的表现更奇怪(如果人们间接期望代码点是连续的)。

    不过,我不知道这样做有什么特别好的理由,或者最初甚至考虑过这种权衡。在 Haskell 1.4 中,Char 只是一个 16 位类型,因此很自然地将其扩展到 17*2^16 值而不添加额外检查。这个问题偶尔会被提出——我以前也提出过——但大多数人似乎并不十分担心。不过,提交一个关于它的 GHC 错误可能是合理的,以便进行适当的讨论。

    请注意Data.Text(它使用 UTF-16 作为其内部表示)does disallow 是无效的代码单元(它必须这样做)。

    【讨论】:

    • 是的,我收集了很多。我所说的有界是指 Char 的使用受限于有界和枚举的实例。我正在使用 Parsec 构建一个解析器,当我在限制 anyChar 和 oneOf 时发现了这一点(有几个有效的 unicode 代码点,我想在我的项目范围内禁止)。无论哪种方式,它都不会影响我,因为我一开始就使用文本流,发现它真是令人惊讶。
    • @MikeMenzel Bounded 和 Enum 都不要求它们的实例是连续的。
    • 就Bounded 而言,“连续”甚至没有确切的含义。只有当您转换为Ints 或从Ints 转换并在该表示中看到一个漏洞时,它才会出现。
    猜你喜欢
    • 2011-03-25
    • 2011-06-30
    • 2019-05-21
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多