Zulip Chat Archive
Stream: new members
Topic: Pattern matching help
Dominic Steinitz (Oct 04 2024 at 09:01):
This may be the equivalent of real programmers can write fortran in any language but I get
invalid pattern, constructor or constant marked with '[match_pattern]' expected
def HHaskell {α : Type} [LinearOrderedField α] (n : ℕ) (k : ℕ) (_ : 2 * k - 1 ≤ 2^n - 1) (s : α) : ℤ :=
let k' := 2 * k + 1
match true with
| (k' - 1) * 2^(-n : ℤ) < s ∧ s <= k' * 2^(-n : ℤ) => 2^((n - 1) / 2)
| k' * 2^(-n : ℤ) < s ∧ s <= (k' + 1) * 2^(-n : ℤ) => -2^((n - 1) / 2)
| _ => 0
Henrik Böving (Oct 04 2024 at 09:03):
That's just not a pattern you can match on
Dominic Steinitz (Oct 04 2024 at 09:06):
I can write this but pattern matching would be clearer
def HHaskell {α : Type} [LinearOrderedField α] (n : ℕ) (k : ℕ) (_ : 2 * k - 1 ≤ 2^n -1) (s : α) : ℤ :=
let k':= 2 * k + 1
if (k' - 1) * 2^(-n : ℤ) < s ∧ s <= k' * 2^(-n : ℤ)
then 2^((n - 1) / 2)
else if k' * 2^(-n : ℤ) < s && s <= (k' + 1) * 2^(-n : ℤ)
then -2^((n - 1) / 2)
else 0
Here's the Haskell for reference
> haar :: forall n k .
> (KnownNat n, KnownNat k, (2 * k - 1 <=? 2^n - 1) ~ 'True) =>
> Haar n (2 * k - 1)
> haar = Haar g where
> g t | (k' - 1) * 2 ** (-n') < t && t <= k' * 2 ** (-n') = 2 ** ((n' - 1) / 2)
> | k' * 2 ** (-n') < t && t <= (k' + 1) * 2 ** (-n') = -2 ** ((n' - 1) / 2)
> | otherwise = 0
> where
> n' = fromIntegral (natVal (Proxy :: Proxy n))
> k' = 2 * (fromIntegral (natVal (Proxy :: Proxy k))) - 1
Henrik Böving (Oct 04 2024 at 09:14):
Yes, Lean doesn't do pattern guards
Paige Thomas (Oct 23 2024 at 04:45):
Henrik Böving said:
Yes, Lean doesn't do pattern guards
Is there a canonical way to emulate pattern guards, where if a guard evaluates to false, then the next pattern is tried?
Kyle Miller (Oct 23 2024 at 05:07):
No, no pattern guards unfortunately. The next best thing is to add extra discriminants that evaluate to true
or false
with your conditions, but that's usually pretty awkward.
Paige Thomas (Oct 23 2024 at 05:23):
By extra discriminants, do you mean extra patterns, or something else?
Paige Thomas (Oct 23 2024 at 05:26):
I can add an if, then, else after the pattern, but I'm not sure how to make it go to the next pattern based on the if, then, else.
Kyle Miller (Oct 23 2024 at 05:26):
I mean match val, cond1, cond2, cond3 where
, where cond1
, cond2
, and cond3
are somehow able to be evaluated from val
before pattern matching, and then you use true
/false
in the patterns for these three discriminants.
Kyle Miller (Oct 23 2024 at 05:27):
It's awkward and not always applicable.
Kyle Miller (Oct 23 2024 at 05:28):
Issue lean4#1894 tracks having more complicated if
conditions that can bind patterns and have guards.
Paige Thomas (Oct 23 2024 at 05:34):
I see. Yeah, I was thinking of the case where the conditional in the guard uses part of the matched pattern, like isval
here: https://www.cis.upenn.edu/~bcpierce/tapl/checkers/untyped/core.ml
Paige Thomas (Oct 23 2024 at 05:36):
I can get around it in my simpler translation for now though.
Kyle Miller (Oct 23 2024 at 05:43):
An annoying way to address it is to make a separate function that does the match and evaluates the guard, and then you put that in as an extra discriminant...
Kyle Miller (Oct 23 2024 at 05:44):
Imagine having Tm.appV1?
and Tm.AppV2?
functions, and then you use Option.map
to apply the guard's function
Paige Thomas (Oct 23 2024 at 05:49):
Does the RFC you linked cover this case? I don't entirely follow the discussion there.
Kyle Miller (Oct 23 2024 at 05:59):
No, the RFC would let you write that ML like (modulo some notation questions)
def eval1 ctx t :=
if (let TmApp fi (TmAbs _ x t12) v2 := t) && isval ctx v2 then
termSubstTop v2 t12
else if (let TmApp fi v1 t2 := t) && isval ctx v1 then
let t2' := eval1 ctx t2 in
TmApp fi v1 t2'
else let TmApp fi t1 t2 := t then
let t1' = eval1 ctx t1 in
TmApp fi t1' t2
else
throw NoRuleApplies
Paige Thomas (Oct 23 2024 at 06:02):
I see.
Paige Thomas (Oct 23 2024 at 06:20):
Is it a feasible feature request to add pattern guards?
Last updated: May 02 2025 at 03:31 UTC