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: Guillaume Yziquel <guillaume.yziquel@c...>
Subject: Re: [Caml-list] Cannot safely evaluate the definition of the recursively-defined module
Hello.

Sorry for reviving this short thread. I have the same error message, but 
I really do not understand what "safety" means in this context.

If I specify the signature of the recursive module, shouldn't the type 
checker work out right out of the box?

Sorry, but I'm a bit confused. You'll find the recursive submodule that 
I'm having problems with below Hugo's email.

All the best,

Guillaume Yziquel.

Hugo Ferreira a écrit :
> Michael Furr wrote:
>>
>> 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:
>>
> 
> Ok, I understand this.
> 
> Thanks,
> Hugo F.
> 
> 
>> ----
>> 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

Here's my recursive submodule:

> module rec Registry : sig
> 
>   val new_status_signal : t -> status React.signal
>   val registry : (t * status React.signal) list React.signal
>   val status_of_agent : t -> status
> 
> end = struct 
> 
>   let new_status_signal agent = React.S.fold
>     begin function current_status -> function
>       | AgentPresent (agent_of_signal, status_information) ->
>           begin match agent = agent_of_signal with
>           | false -> current_status
>           | true -> status_information
>           end
>       | AsteriskStatus (Asterisk.Active activity) ->
>           let agent_ip = match Registry.status_of_agent agent with
>           | Present ip -> Some ip
>           | Online (ip, _) -> Some ip
>           | _ -> None in
>           begin match agent_ip with None -> current_status
>           | Some ip -> current_status (* To do... *)
>           end
>       | AsteriskStatus _ -> current_status
>     end Offline (React.E.select [
>       agent_status_notification;
>       (React.E.map begin function s -> AsteriskStatus s end
>         (Asterisk.server # status_change))
>     ])
> 
>   let registry = React.S.fold
>     begin fun live_registry new_agent -> new_agent::live_registry end
>     begin Lwt_main.run (persistent_registry >>= Ocsipersist.get >>=
>       begin function a_list -> Lwt.return (List.map
>         begin function (nom, prenom) ->
>           let a = {nom = nom; prenom = prenom} in
>           a, (Registry.new_status_signal a)
>         end a_list)
>       end)
>     end
>     begin React.E.map
>       begin function agent -> agent, (Registry.new_status_signal agent) end
>       adding_to_registry
>     end
> 
>   let status_of_agent agent =
>     try React.S.value (List.assoc agent (React.S.value Registry.registry))
>     with Not_found -> raise (invalid_arg ("Agent.status_of_agent: "^agent.prenom^" "^agent.nom))
> 
> end


-- 
      Guillaume Yziquel
http://yziquel.homelinux.org/