gpt4 book ai didi

types - 通配符模式覆盖多态变体的子类型约束

转载 作者:行者123 更新时间:2023-12-04 14:23:14 26 4
gpt4 key购买 nike

鉴于这些类型

type a = [ `A ]
type b = [ a | `B | `C ]

和这个功能

let pp: [< b] -> string =
function | `A -> "A"
| `B -> "B"
| `C -> "C"

应用 a 类型的值按预期工作没有问题:

let a: a = `A
let _ = pp a

但是,如果修改函数以包含通配符模式

let pp: [< b] -> string =
function | `A -> "A"
| `B -> "B"
| _ -> "?"

即使其他一切都保持不变,它现在会产生以下错误(在 let _ = pp a 上):

This expression has type b -> string but an expression was expected of type a -> 'a Type b = [ `A | `B ] is not compatible with type a = [ `A ] The second variant type does not allow tag(s) `B



问题:
  • 为什么它不再能够接受子类型?我理解通配符意味着它现在可以接受父类(super class)型,但这不应该意味着它必须。
  • 有没有办法解决这个问题,以避免枚举一百万左右不相关的变体?
  • 最佳答案

    根本的问题是为什么

    let pp= function
    | `A -> "A"
    | `B -> "B"
    | _ -> "?"

    推断为 [> `A| `B] -> string而不是 [< `A| `B | ... ] -> string (其中 ... 代表任何构造函数)。答案是这是一个设计选择,也是一个假阳性和假阴性之间的折衷问题: https://www.math.nagoya-u.ac.jp/~garrigue/papers/matching.pdf .

    更准确地说,第二种类型被认为太弱了,因为它太容易丢失 `A 的信息。和 `B出现在 pp .例如,考虑以下代码,其中 `b是拼写错误,应该是 `B :
    let restrict (`A | `b) = ()
    let dual x = restrict x, pp x

    目前,此代码失败

    Error: This expression has type [< `A | `b] but an expression was expected of type [> `A | `B ]
    The first variant type does not allow tag(s) `B



    此时,如果 `b是一个拼写错误,在这里可以发现错误。如 pp已输入 [< `A|`B |..] ,双重类型将被限制为 [`A] -> unit * string默默地,没有机会捕获这个错误。此外,以当前的类型,如果 `b不是拼写错误,完全有可能使 dual通过添加一些强制转换有效
    let dual x = restrict x, pp (x:[`A]:>[>`A]);;
    (* or *)
    let dual x = restrict x, (pp:>[`A] -> _) x

    非常明确地表明 restrictpp适用于不同的多态变体集。

    关于types - 通配符模式覆盖多态变体的子类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47212094/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com