Version française
Home     About     Download     Resources     Contact us    
Browse thread
Cannot safely evaluate the definition of the recursively-defined module
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Michael Furr <furr@c...>
Subject: Re: [Caml-list] Cannot safely evaluate the definition of the recursively-defined module

On Wed, 18 Mar 2009, Hugo Ferreira wrote:

> I hope this is not a beginners questions.
> I am trying to reuse code via functors,
> however I am getting the following error:
>
> Cannot safely evaluate the definition of the recursively-defined module
> (refers to "AA.empty" when implemented as a constant value)
>
> I circumvented the problem by not using a
> constant value but a function instead. As I
> understand it this may cause run-time errors.
> My question is: is their any way to make the
> following example work.

If you only need to store a constant value in the module, then you can get 
around the restriction by splitting the module into a (recursively-)safe 
module, and an extension that adds the constants.  Here is a slightly 
modified version of your code showing the transformation:

----
module type AA_Safe =
sig
   type q
   type t = string

   val compare: t -> t -> int
   val add: t -> q -> q
   (* omit empty here, since it is not "safe" *)
end

module rec A1 : AA_Safe with type q = ASet.t  =
struct
   type q = ASet.t
   type t = string
   let compare s1 s2 = Pervasives.compare s1 s2
   let add e s = ASet.add e s
end
and ASet : Set.S with type elt = A1.t = Set.Make(A1)

(* now create the full module *)
module type AA = sig
   include AA_Safe
   val empty: q
end

module A2 : AA = struct
   include A1
   let empty = ASet.empty
end

module type Wrap_A =
sig
   type t
   type q

   val init: q
   val add: t -> q -> q
end
module Make_A (An_A : AA) : Wrap_A
   =
struct
   type t = An_A.t
   type q = An_A.q

   (*let init = ASet.empty*)
   let init = An_A.empty
   let add t q = An_A.add t q
end

module Wrap_A1 = Make_A( A2 )
----

Cheers,
-Mike