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