compiler-errors - 不允许使用表单,因为内联记录的类型可能会逃逸

标签 compiler-errors ocaml record

type 'a queue = Q of {estack : 'a list; dstack : 'a list} | Empty

let enqueue d q = match q with  
    | Empty -> Q {estack = [d]; dstack = []}
    | _ -> Q {q with estack = q.estack :: d} 

为什么编译器会提示?

This form is not allowed as the type of the inlined record could escape.

最佳答案

您很可能想编写一些变体

let enqueue d q = match q with  
| Empty -> Q {estack = d; dstack = []}
| Q r -> Q {r with estack = r.estack @ d} 

编译器错误 这种形式是不允许的,因为内联记录的类型可能会转义源于内联记录在 OCaml 中不完全是第一类对象的事实。特别是,它们不能在其构造函数的上下文之外使用。因此,当类型检查 Q { q with … } 时,类型检查器尝试将变量 q 的类型与 Q 的类型统一>-内联记录并引发错误,因为这种统一会将 Q 的内联记录泄漏到外部变量 q

编辑:

由于您编辑的版本存在完全相同的问题,因此这里是 修正后的版本

let enqueue d q = match q with  
    | Empty -> Q {estack = [d]; dstack = []}
    | Q r -> Q {r with estack = d :: r.estack};; 

和以前一样,问题在于 Q { q with … } q 的类型为 'a enqueue 而构造函数 Q 期望'a enqueue.Q.inlined_record 类型的变量作为参数;它在 OCaml 表面语言中没有明确的名称。因此,需要首先通过 Q r 上的模式匹配提取内部记录,然后使用 Q { r with … } 更新该记录。

关于compiler-errors - 不允许使用表单,因为内联记录的类型可能会逃逸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42893124/

相关文章:

maven - 如何使用 maven 获得完整的 javac 编译器错误?

c++ - 编译 C++ 代码时出错?

polymorphism - 为什么是弱多态类型?

windows - 为什么录音机代码可以工作8位,但不能工作16位?

ocaml - 在同一记录的其他字段中使用记录字段

android - 在较低的API级别上测试Android应用的正确方法(Android Studio)

PHP 语法错误,我是瞎了吗?

module - 隐藏在 OCaml 中的外部和内部接口(interface)和信息

performance - OCaml 中的恒定时间列表串联

android - 未在核心格式中列出的Google Ion提供哪些记录格式?