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}
为什么编译器抱怨?
不允许使用此表单,因为内联记录的类型可以 逃。
你很可能想写一些变体
let enqueue d q = match q with
| Empty -> Q {estack = d; dstack = []}
| Q r -> Q {r with estack = r.estack @ d}
编译器错误This form is not allowed as the type of the inlined record could escape
源于这样一个事实,即内联记录在 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 … }
更新此记录。