Support interface composition (<+>) and abstraction (Use) in FreeSpec.Exec
lthms opened this issue · comments
Thomas Letan commented
Currently, the examples of FreeSpec.Exec only works because the typeclass inference of Coq eagerly replaces {Use i ix}, ix
into i
.
Using two different interfaces breaks that trick, as shown by the following example:
Require Import Prelude.Control.
Require Import FreeSpec.Program.
Inductive i1 (a: Type): Type := wrap: a -> i1 a.
Inductive i2 (a: Type): Type := unwrap: i2 a.
Arguments wrap [a] (_).
Arguments unwrap [a].
Local Open Scope prelude_scope.
Definition test {ix} `{Use i1 ix} `{Use i2 ix} : Program ix nat :=
request (wrap 2) ;;
request unwrap.
Eval compute in test.
Output is:
= Request ((let (lift_eff) := ?H in lift_eff) nat (wrap 2))
(fun _ : nat =>
Request ((let (lift_eff) := ?H0 in lift_eff) nat unwrap) (Pure (A:=nat)))
: Program ?ix nat
Similarly, using the <+>
operator to compose interfaces together would also break FreeSpec.Exec.