首页 > 解决方案 > 类型与列表操作不匹配

问题描述

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.

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

标签: ocaml

解决方案


您在这里省略了很多上下文,我必须删除对缺失模块的引用才能重现,这意味着我做了几个可能错误的假设。

鉴于此,我的猜测是您复制了最初使用 Base 或 Core 标准库替换的代码,其中List.nth函数返回一个'a option,而不是标准 OCaml 实现,如果给定索引超出范围,则会引发异常.

我这么认为的原因是该parent字段dec具有类型dec option并且是直接分配的last_scope,这意味着last_scope必须具有相同的类型。如果List.nth有类型'a list -> int -> 'a,则'a必须有类型dec option,这意味着table必须有类型dec option list。而且您不能将 adec添加到 a dec option list,因此会出现错误。

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


推荐阅读