Home     About     Download     Resources     Contact us

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

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: 2009-03-19 (04:02) From: Michael Furr 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

```