Search code examples
ocamlfunctor

The module Map.Make is a functor, it cannot have any components


I want to have a Map datastructure for "env" in my lisp interpreter.

My code in env.mli is

module Env = Map.Make(String)

type t = (Ast.expression) Env.t

val empty: t

val add: string -> Ast.expression -> t -> t

val lookup: string -> t -> Ast.expression

But my code in env.ml is:

module Env = Map.Make(String)

type t = (Ast.expression) Env.t

let (empty: t) = Env.empty

let add (id: string) (value: Ast.expression) (env: t): t = Env.add id (value) env

let lookup (id: string) (env: t) : Ast.expression = Env.find id env

And there aren't any error prompt. Curious about why and how to modify my code. Quite new to functors and maybe I didn't fully understand it.

Thank you.


Solution

  • Based on the little information you provide, my guess is that what you want is to expose the Env fully as a map over strings. If so, you should replace

    module Env = Map.Make(String)
    

    with

    module Env : Map.S with type key = string
    

    but you could also leave the key type abstract:

    module Env : Map.S
    

    or expose only the type of the map:

    module Env : sig 
      type 'a env
    
      type t = e env
    
      ...
    end = struct 
      module Env = Map.Make(String) 
    
      type 'a env = 'a Env.t
          
      type t = Ast.expression Env.t
    
      ...
    end
    

    or you could make t itself abstract, to avoid referencing the env/map type at all:

    module Env : sig 
      type t
    
      ...
    end = struct 
      module Env = Map.Make(String) 
    
      type t = Ast.expression Env.t
    
      ...
    end
    

    There's many possible solutions depending on what you actually need it for.