Effect with a value

Hello,
I have been trying to create an effect like this to return a int. What types can I return like this ?

type _ Effect.t += Early_return : int -> int Effect.t

But didn’t manage to fix this error. Am I misunderstanding the type of the effect ?
I am aware that the syntax can be simplified when I use the new release.

type _ Effect.t += Early_return : int -> int Effect.t
  let rec  effective_request_vote mutex id term votes_received =
  match_with (fun () -> requestvote mutex id term votes_received)
    ()
  { effc = (fun (type c) (eff1: c Effect.t) ->
      match eff1 with
      | Early_return  v -> Some (fun (k:  (c,_) continuation) ->
              Printf.printf "Early Return" ;
              continue k v
          )
      | _ -> None
  );
  exnc = (function
        | e -> raise e
  );
  retc = (fun _ ->  ())

 }

The error is

perform (Early_return votes_received )
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This constructor has type “int eff”
but an expression was expected of type “('a → 'b) eff”
Type “int” is not compatible with type “'a → 'b”

Update : I mistyped my code. Updated it now. This was the original error.
Thanks,
Mohan

Hi! I try to reproduce your case in ocaml 5.3.0 and I did’nt face to any errors

The issue probably lies outside the code you showed (the code you posted looks correct, but we don’t see the perform part in there).
This is likely a mismatch between the input and return types of perform: Early_return declares that performing it returns an integer, but the type-checker seems to assume the the result of the perform expression is a function, which could happen for instance if you passed an extra argument (perform (Early_return votes_received) foo) or if it occurs in a branch and the other branch was inferred to be a function (either correctly or because you forgot an argument to a function call).
You can add type annotations like (perform (Early_return votes_received) : int) to try to get a more useful type error.

As you mentioned it seems to be caused at the callsite. I am investigating.

Update :

I have code that works now.

type _ Effect.t += Early_return :  int -> int Effect.t

let rec effective_request_vote
  (mutex : Eio.Mutex.t)
  (id : int)
  (term : int)
  (votes_received : int) : int Lwt.t =

  match_with (fun () -> requestvote mutex id term votes_received)
    ()
  { effc = (fun (type c) (eff1: c Effect.t) ->
      match eff1 with
      | Early_return v  -> Some (fun (k:  (c,_) continuation) ->
              Printf.printf "Early Return" ;
              continue k v
          )
      | _ -> None
  );
  exnc = (function
        | e -> raise e
  );
  retc = (fun _ ->  Lwt.return votes_received)

 }
 

I had to change the retc and fix it like this in the function that produces that effect. Annotations helped really.

    Lwt.return (perform (Early_return votes_received));

I had to do this because the call to the function that produces that effect Early_return
expects Lwt.t since it mixes EIO and LWT. I believe I should use only EIO henceforth as I am not a seasoned OCaml dev.

The combination of effect handlers, LWT and EIO is hard

Thanks

1 Like