Search code examples
ocaml

OCaml: Type mismatch error between modules


ast.ml

type fundef = FunDef of string * string list * expr

interpreter.ml

let interp_fundef (d: Ast.fundef) (g: FStore.t) : FStore.t = 
  match d with
  | Ast.FunDef (x, pl, e) -> (FStore.add x (pl * e) g)

fStore.ml

module M = Map.Make(String)

type t = (string list * Ast.expr) M.t

let add = M.add

let mem = M.mem

let find = M.find

let empty = M.empty

I am making a f1vae AST interpreter with OCaml and above is my current code. When compilng, I am getting this error on pl in interpreter.ml:

Error: This expression has type string list
       but an expression was expected of type int

Why is this happening?


Solution

  • If g is of type FStore.t then the map holds a tuple of type string list * Ast.expr. However, you have tried to add into that map (pl * e). Here the operator * dictates that pl and e must be values of type int.

    You likely meant to write the following, which creates a tuple of pl and e using a comma.

    let interp_fundef (d: Ast.fundef) (g: FStore.t) : FStore.t = 
      match d with
      | Ast.FunDef (x, pl, e) -> (FStore.add x (pl, e) g)
    

    This mistake based on the disparity between tuple type and tuple value syntax is easy to make, but fundamental, so important to understand.

    # (4, 5);;
    - : int * int = (4, 5)
    

    I might suggest writing this as follows, avoiding binding the unneeded d name.

    let interp_fundef (Ast.Fundef (x, pl, e)) (g : FStore.t) : FStore.t =
      FStore.add x (pl, e) g