I’m experimenting with intercepting effects as in order to attach information to them, for example in order to prioritise certain fibres.
This as an idea seemingly does work, although there is many slightly weird type errors.
Throughout this I’m using the
After much trial and error here is a working example.
effect Get : string effect Priority : 'a eff * string -> 'a let run f ~init = let comp = match f () with | x -> (fun s -> x) | effect (Priority (Get, p)) k -> (fun (s : string) -> print_endline p; continue k s s) in comp init let priority f ~p = match f () with | x -> x | effect Get k -> let r = perform (Priority (Get, p)) in continue k r;; let () = run ~init:"1" @@ @@ fun () -> priority ~p:"p" @@ print_endline (perform Get)
Unfortunately I don’t quite understand how some of the typing constraints passes around.
For example one persistent problem was that if
s is not constrained to be a
string its usage in the
continue k s s fails to type check:
Error: This expression has type 'a but an expression was expected of type effect This instance of effect is ambiguous: it would escape the scope of its equation
Why is it expecting the type to be an
Additionally one change which would be nice to have would be to pass the continuation up through the priority effect, such that on the return the priority function would not need to be involved, ie:
effect Priority : 'a eff * ('a, 'b) continuation * string -> unit let run f ~init = let comp = match f () with | x -> (fun s -> x) | effect (Priority (Get, k, _)) _ -> fun (s : string) -> continue k s s in comp init
All variants I’ve tried to write using this unfortunately unify the
effect, but I am not sure why this is occurring, if I manually type
'b : int,
run type checks, but then it is not polymorphic.
Finally one nice simplification in these situations may be to have a match statement as follows:
let run f ~init = let comp = match f () with | x -> (fun s -> s) | effect (Priority (Get, k, _)) _ | effect Get k -> fun (s : string) -> continue k s s
However this fails with the error:
Effect patterns must be at the top level of a match case
Are these style of patterns just not possible using effects? I am fairly sure that it was possible to do similar patterns for exceptions, though I am probably mistaken.
I’m expecting that the answer to the first two of these is that I need to better constrain the type of
Priority, which I would love to hear how to do this .
If there is some underlying issue with this approach that would also be great to hear!
Overall though the new effects system is very very cool, super versatile and expressive!