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/