coq – 将模式传递给战术

我正在编写一种策略来查找与绑定列表中的键相关联的值.就像是:

Require Import String List Program.

Ltac assoc needle haystack :=
  match haystack with
  | @nil (_ * ?T) => constr:(@None T)
  | cons (?k, ?v) ?t => let pr := constr:(eq_refl k : k = needle) in constr:(Some v)
  | cons _        ?t => let res := assoc needle t in constr:res
  end.

不幸的是,我不知道钥匙的确切形式;相反,我知道一个匹配它的模式.更准确地说,我正在寻找的关键是调用类型类方法的结果,但我事先并不知道将使用哪个实例.在下面的例子中,我知道键是一个显示“a”的调用,但我不知道具有什么实例:

Open Scope string_scope.
Open Scope list_scope.

Class Show A := { show: A -> string }.
Instance Show1 : Show string := {| show := fun x => x |}.
Instance Show2 : Show string := {| show := fun x => x ++ x |}.

Goal True.
  (* Works (poses Some 1) *)
  let v := assoc (show "a") [(show (Show := Show2) "a", 1); ("b", 2)] in pose v.
  (* Does not work (poses None) *)
  let v := assoc (show "a") [(show (Show := Show1) "a", 1); ("b", 2)] in pose v.

有没有我可以在这里使用的技巧,没有通过关联检查匹配的ltac?理想情况下它看起来像(show(Show:= _)“a”),或者(fun inst => show(Show:= inst)“a”).

最佳答案 看起来像传递函数很好地工作,实际上:

Ltac assoc needlef haystack :=
  match haystack with
  | @nil (_ * ?T) => constr:(@None T)
  | cons (?k, ?v) ?t => let pr := constr:(eq_refl k : k = needlef _) in constr:(Some v)
  | cons _        ?t => let res := assoc needlef t in constr:res
  end.

Goal False.
  let v := assoc (fun i => show (Show := i) "a") [(show (Show := Show2) "a", 1); ("b", 2)] in pose v.
  let v := assoc (fun i => show (Show := i) "a") [(show (Show := Show1) "a", 1); ("b", 2)] in pose v.
点赞