目前我正在阅读Certified Programming with Dependent Types及其exercise。
在练习中的HW12.v
中,异构列表被定义为
Section hlist.
Variable A : Type.
Variable B : A -> Type.
Inductive hlist : list A -> Type :=
| HNil : hlist nil
| HCons : forall (x : A) (ls : list A), B x -> hlist ls -> hlist (x :: ls).
Variable elm : A.
Inductive member : list A -> Type :=
| HFirst : forall ls, member (elm :: ls)
| HNext : forall x ls, member ls -> member (x :: ls).
Fixpoint hget ls (mls : hlist ls) : member ls -> B elm :=
match mls with
| HNil => fun mem =>
match mem in member ls' return (match ls' with
| nil => B elm
| _ :: _ => unit
end) with
| HFirst _ => tt
| HNext _ => tt
end
| HCons x mls' => fun mem =>
match mem in member ls' return (match ls' with
| nil => Empty_set
| x' :: ls'' =>
B x' -> (member ls'' -> B elm)
-> B elm
end) with
| HFirst _ => fun x _ => x
| HNext mem' => fun _ get_mls' => get_mls' mem'
end x (hget mls')
end.
End hlist.
为了猜测为什么在HCons
模式中使用护送模式,我试图将其重写为
| HCons x mls' => fun mem =>
match mem in member ls' return (match ls' with
| nil => Empty_set
| _ :: _ => B elm
end) with
| HFirst _ => x
| HNext _ mem' => (hget mls') mem'
end
然后Coq没有接受更改,但错误发生在HNil
模式中,如下所示。
Error:
In environment
A : Type
B : A -> Type
elm : A
hget : forall ls : list A, hlist ls -> member ls -> B elm
ls : list A
mls : hlist ls
mem : member ?l@{l0:=nil}
The term
"match mem in (member ls') return match ls' with
| nil => B elm
| _ :: _ => unit
end with
| HFirst _ => tt
| HNext _ _ => tt
end" has type "match ?l@{l0:=nil} with
| nil => B elm
| _ :: _ => unit
end" while it is expected to have type "B elm".
如果HCons
模式中出现错误,这是合理的,但为什么在HNil
中,为什么曾经被正确推理过?