Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
995 views
in Technique[技术] by (71.8m points)

ocaml - Type mismatch with operation on lists

New in Ocaml and I'm trying to implement a couple of functions to manage a list of a custom types.

I'm trying to manage a list of types, and when I need to add a new element to the list I need to make some checks. This is my actual code:

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"

I'm trying to implement the operation begin_block but I'm getting the following error:

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.

In this case, the table is the list I'm losing somethings but at the moment I'm not able to find the error :/, maybe this is a stupid question.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're omitting a lot of context here, and I had to remove references to missing modules in order to reproduce, which means I've made several assumptions that may be wrong.

Given that, my guess is that you've copied code that originally used the Base or Core standard library replacement, where the List.nth function returns an 'a option, as opposed to the standard OCaml implementation which will raise an exception instead if the given index is out of bounds.

The reason I think so is that the parent field of dec has type dec option and is assigned last_scope directly, which means last_scope must have the same type. And if List.nth has type 'a list -> int -> 'a, then 'a must have type dec option, which means table must have type dec option list. And you can't prepend a dec to a dec option list, hence the error.

Lastly, a good way to find the cause of issues like this is to make your assumptions explicit by annotating the type of variables. For example, annotating the type of table here will give you a different error, narrowing it down last_scope having the type dec but being expected to have type dec option when being assigned to parent.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...