Quantcast
Channel: Active questions tagged ocaml - Stack Overflow
Viewing all articles
Browse latest Browse all 518

Nesting algebraic handlers from separate modules

$
0
0

Can algebraic handlers in OCaml be separated and put into different modules, then be nested together in some other file?

For instance, say you have a program in a file called program.ml that uses a user-defined function put: int -> unit that modifies a variable x. In this scenario, there is an effect Put_found: int -> unit Effect.t and put is defined as

put n = x:= n; perform(Put_found n)

A sample program would look like: put(5);put(0).

There are also two compilation units Handler1 and Handler2, each with their ml and mli files. The former contains a function run_h1 that when given the sample program as input, the handler acts on the effect Put_found by printing the integer passed to it. Then, it raises another effect Report_p, which is to be passed to the second handler. run_h1 returns a function of type unit -> unit as looks like this:

let run_h1 () = fun () -> match_with Program.comp () {effc = (fun (type c) (eff: c Effect.t) ->    match eff with    | Put_found s -> Some (fun (k : (c,_) continuation) ->            report_p(s); continue k ())    | _ -> None  );}

The second effect, Report_p of type int -> unit Effect.t, is to be handled by a function found in Handler2 such that if the integer passed is negative, an error message is printed to the screen.

run_h2 is the following function:

let run_h2 inst x = match_with inst x{    effc = (fun (type b) (eff: b Effect.t) ->      match eff with      | Report n -> Some (fun (k: (b,_) continuation) ->         if n = (-1) then printf "Put with value -1 encountered.\n" else printf "Put found with allowed value.\n"; continue k ())      | _ -> None    );    exnc = raise;    retc = fun x-> x}

In another file, run_handlers.ml, I make use of the compilation units mentioned above as follows:

let run_handlers () = Handler2.run_h2(Handler1.run_h1 ()) ()

When at first the program and effects were found in the same file and the handlers were nested in the same file, the program worked fine. Here is what it looked like:
The program looked like this:

let run_h2 () =   let comp () = put(5); put(6); put(-1); put(100) in  let run_h1 () = match_with comp ()  { effc = (fun (type c) (eff: c Effect.t) ->      match eff with      | Put_found s -> Some (fun (k: (c,_) continuation) ->              report_p(s); continue k ())      | _ -> None    );    exnc = raise;    retc = fun x-> x  } in  match_with run_h1 () {    effc = (fun (type b) (eff: b Effect.t) ->      match eff with      | Report n -> Some (fun (k: (b,_) continuation) ->         if n = (-1) then printf "Put with value -1 encountered.\n" else printf "Put found with value: %d\n" (n); continue k ())      | _ -> None    );    exnc = raise;    retc = fun x-> x  }

Now, I am trying to modularise it, but a Stdlib.Effect.Unhandled exception was thrown on the first instance the effect should be performed.


Viewing all articles
Browse latest Browse all 518

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>