不允许使用表单,因为内联记录的类型可能会转义


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 … }更新此记录。

最新更新