Skip to content

Instantly share code, notes, and snippets.

@zehnpaard
Last active January 8, 2023 03:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zehnpaard/8db5956b5cb217ceba12d8608b8deafc to your computer and use it in GitHub Desktop.
Save zehnpaard/8db5956b5cb217ceba12d8608b8deafc to your computer and use it in GitHub Desktop.
Implementation of mutually recursive is_odd and is_even, splitting the definition across modules using OCaml 5.0 effect handlers
module Base = struct
type _ Effect.t +=
| IsOdd: int -> bool Effect.t
| IsEven: int -> bool Effect.t
end
module Odd = struct
let is_odd n =
if n=0 then false
else Effect.perform (Base.IsEven (n-1))
end
module Even = struct
let is_even n =
if n=0 then true
else Effect.perform (Base.IsOdd (n-1))
end
module M = struct
module D = Effect.Deep
let rec handler : 'a. 'a D.effect_handler =
{
D.effc = fun (type b) (eff : b Effect.t) ->
match eff with
| Base.IsEven n -> Some (fun (k: (b,_) D.continuation) ->
D.continue k @@ D.try_with Even.is_even n handler)
| Base.IsOdd n -> Some (fun (k: (b,_) D.continuation) ->
D.continue k @@ D.try_with Odd.is_odd n handler)
| _ -> None
}
let is_odd n = D.try_with Odd.is_odd n handler
let is_even n = D.try_with Even.is_even n handler
end
let () = print_endline @@ string_of_bool @@ M.is_odd 72
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment