
effect Foo : (unit -> unit)
effect Goo : (unit -> unit)

let f () 
(*@  requires (true, emp, ())   @*)
(*@  ensures  (true, (Foo!).(Goo!).Goo?().Foo?(), ()) @*)
= 
  let x = perform Foo in 
  let y = perform Goo in 
  y ();
  x ()

let handler 
(*@  requires (true, emp, ())   @*)
@   ensures   ( true ,  ! ) , ( ) ) @
= 
  match f () with 
  | x -> perform AftDone
  | effect Foo k -> perform BefFoo; continue k (fun () -> ()); continue k (fun () -> ()) ; perform AftFoo
  | effect Goo k -> perform BefGoo; continue k (fun () -> ()); perform AftGoo;

@  requires (true, emp, ())   @
@  ensures  (true, (Foo!).(Goo!).Goo?().Foo?(), ()) @
@  requires (true, emp, ())   @

effect Foo : (unit -> unit)
effect Goo : (unit -> unit)

let f () 
= 
  let x = perform Foo in 
  let y = perform Goo in 
  y ();
  x ()

let handler 
@   ensures   ( true ,  ! ) , ( ) ) @
= 
  match f () with 
  | x -> perform AftDone
  | effect Foo k -> perform BefFoo; continue k (fun () -> ()); continue k (fun () -> ()) ; perform AftFoo
  | effect Goo k -> perform BefGoo; continue k (fun () -> ()); perform AftGoo;
