类型与列表操作不匹配

Type mismatch with operation on lists

Ocaml 中的新功能,我正在尝试实现几个函数来管理自定义类型列表。

我正在尝试管理一个类型列表,当我需要向列表中添加一个新元素时,我需要进行一些检查。 这是我的实际代码:

open Ast
open Easy_logging
exception DuplicateEntry

let logger = Logging.make_logger "SymbolTable" Debug [Cli Debug]

type variable = {
  id: string;
  tipe: Ast.typ
}

type dec = {
  variables: variable list;
  parent: dec option
}

let begin_block table =
  if List.length table > 1 then
     let last_scope = List.nth table ((List.length table) -1) in
     let new_scope = {variables=[]; parent=last_scope} in
     new_scope::table
  else {variables=[]; parent=None}::table

let add_entry symbol info table =
  let tail_scope = List.nth table ((List.length table) - 1) in
  {id=symbol; tipe=info}::tail_scope.variables;
  logger#debug "Added inside the table the node with id %s" symbol

let rec lookup symbol table = failwith "lookup: Not implemented yet"

我正在尝试执行操作 begin_block,但出现以下错误:

File "src/symbol_table.ml", line 31, characters 16-21:
31 |      new_scope::table
                     ^^^^^
Error: This expression has type dec option list
       but an expression was expected of type dec list
       Type dec option is not compatible with type dec 
Command exited with code 2.
Compilation unsuccessful after building 26 targets (0 cached) in 00:00:01.

在这种情况下,table 是列表 我丢失了一些东西,但目前我找不到错误:/,也许这是一个愚蠢的问题。

你在这里省略了很多上下文,我不得不删除对缺失模块的引用以便重现,这意味着我做了几个可能是错误的假设。

鉴于此,我的猜测是您复制了最初使用 Base 或 Core 标准库替换的代码,其中 List.nth 函数 returns 和 'a option,相反到标准的 OCaml 实现,如果给定的索引超出范围,它将引发异常。

之所以这么认为是因为decparent字段的类型是dec option,直接赋值给last_scope,也就是说last_scope必须有相同的类型。如果 List.nth 的类型为 'a list -> int -> 'a,则 'a 的类型必须为 dec option,这意味着 table 的类型必须为 dec option list。而且你不能在 dec option list 前添加 dec,因此会出现错误。

最后,找到此类问题原因的一个好方法是通过注释变量的类型来明确您的假设。例如,在此处注释 table 的类型会给您一个不同的错误,将其缩小为 last_scope 具有类型 dec 但在分配时预期具有类型 dec optionparent.