问题
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