Zulip Chat Archive
Stream: general
Topic: pattern matching 101
Scott Morrison (Apr 25 2018 at 08:39):
Easy question: how do I do pattern matching against values? Given k : nat
, naively I could try writing
match n with | k := something | _ := something_else end
a glorified if n = k then something else something_else
, but of course this doesn't work, because Lean doesn't treat the k
in the pattern as related to the earlier k
.
Am I just meant to use if ... then ... else
? Or can I get the pattern matcher to help me?
Kenny Lau (Apr 25 2018 at 08:40):
you need to use if then else
. match
only deals with constructors.
Scott Morrison (Apr 25 2018 at 08:43):
That's what I feared. How sad. So if I want to write something that given some n
where n = k
does X
, and given any other some n
or none
does Y
... What's the idiomatic way to write this?
Scott Morrison (Apr 25 2018 at 08:43):
(Preferably your answer shouldn't use option.is_some
or friends, just pretend option
is a bare inductive type with no dressing up.)
Scott Morrison (Apr 25 2018 at 08:44):
In particular, how can I do this without writing the symbol Y
twice?
Sebastian Ullrich (Apr 25 2018 at 08:55):
Other languages have pattern guards for this, but Lean doesn't... yet. You'll have to factor Y
out into a let
.
Sean Leather (Apr 25 2018 at 08:55):
That's what I feared. How sad. So if I want to write something that given
some n
wheren = k
doesX
, and given any othersome n
ornone
doesY
... What's the idiomatic way to write this?
This sounds like something you'd use pattern match guards for in Haskell:
case n of Just k | n == k -> something _ -> something_else
Kenny Lau (Apr 25 2018 at 08:56):
In particular, how can I do this without writing the symbol
Y
twice?
if o = some k then _ else Y
Scott Morrison (Apr 25 2018 at 08:57):
okay, good, except I've over-minimised of course, and there are lots of other fields that I don't care about matching :-)
Kenny Lau (Apr 25 2018 at 08:58):
so maybe give us more context?
Simon Hudon (Apr 25 2018 at 13:30):
Is it possible that your type is like the following?
inductive my_type | constr : a -> b -> c -> d -> e -> my_type | other : a' -> b' -> my_type
In Haskell, a common advice is to make that two or more types, separate the sum aspect and the product aspect.
Simon Hudon (Apr 25 2018 at 13:31):
Then, you can use selectors on to access whatever part of the product that you care about
Scott Morrison (Apr 25 2018 at 13:33):
hmm, my type
inductive edit_distance_progress (l₁: list α) (l₂: list α) | exactly : ℕ → edit_distance_progress | at_least : ℕ → partial_edit_distance_data α → edit_distance_progress
Scott Morrison (Apr 25 2018 at 13:33):
and I need to check if I have an exactly _ _ k
for some specified value of k
.
Simon Hudon (Apr 25 2018 at 13:38):
Ok, it's not as bad as I thought. I thought because you didn't want to repeat Y
. Is it a pattern for partial_edit_distance_data α
?
Scott Morrison (Apr 25 2018 at 13:43):
I'm not sure what you mean. The offending code (which works, just looks gross) is <https://github.com/semorrison/lean-tidy/blob/master/src/tidy/rewrite_search.lean#L64-L84>. You can see lines 72-74 and lines 76-78 are almost identical because of this.
Sean Leather (Apr 25 2018 at 13:49):
Why can't you do something like if update_edit_distance h.distance = exactly _ _ k then ... else ...
as Kenny suggested?
Scott Morrison (Apr 25 2018 at 13:51):
Oh... somehow I thought those _
s would be a problem, but of course they're not. Thank you!
Scott Morrison (Apr 25 2018 at 13:53):
I will need an extra decidable instance for this. I remember there is some trick for synthesising decidable instances for boring inductive types....? Anyone remember?
Sean Leather (Apr 25 2018 at 13:54):
@[derive decidable_eq] inductive ...
Scott Morrison (Apr 25 2018 at 13:55):
Lovely! And where do I find out what derive is doing? :-)
Sean Leather (Apr 25 2018 at 13:57):
I'm sure there's a #print
that'll tell you, but I never remember which one. :blush:
Sean Leather (Apr 25 2018 at 13:58):
Perhaps #print <type-name>.decidable_eq
?
Last updated: Dec 20 2023 at 11:08 UTC