Agda: type isn't simplified in `with` block

断了今生、忘了曾经 提交于 2019-12-12 03:37:35

问题


I'm trying to solve the bonus exercise on page 23 of this tutorial, but I can't fill in this hole:

lem-all-filter : {A : Set}(xs : List A)(p : A -> Bool)
              -> All (satisfies p) (filter p xs)
lem-all-filter [] p = all[]
lem-all-filter (x :: xs) p with p x
... | true = {! !} :all: lem-all-filter xs p
... | false = lem-all-filter xs p

If I type C-c C-, in the hole then I get this message:

Goal: isTrue (p x)
--------------------------------
xs : List .A
p  : .A -> Bool
x  : .A
.A : Set

but I would expect the goal to have type True, since p x is true and isTrue true = True. Am I missing something?


回答1:


When you pattern match on p x, p x gets rewritten to the pattern everywhere in the context, but that hole not in the context at the time of rewriting: it appears later and hence p x in its type doesn't get rewritten. You can remember that p x is equal to true using the inspect idiom (deprecated now in favour of inspect on steroids) described later in the paper, but you can also do the following:

lem-all-filter : {A : Set}(xs : List A)(p : A -> Bool)
              -> All (satisfies p) (filter p xs)
lem-all-filter [] p = all[]
lem-all-filter (x :: xs) p with p x | λ (y : isTrue (p x)) -> y :all: lem-all-filter xs p
... | true  | onTrue = onTrue _
... | false | onTrue = lem-all-filter xs p

Here you explicitly introduce the type of the argument to :all: in the context and hence when p x gets rewritten to true, the type of onTrue reduces to True -> All (satisfies p) (x :: filter p xs) as you needed.



来源:https://stackoverflow.com/questions/38572464/agda-type-isnt-simplified-in-with-block

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!