fix: Option.getD eagerly evaluates dflt (#3043)
Reported [on Zulip](https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/Panics.20in.20Std.2EHashMap.2Efind!/near/406872395). The `dflt` argument of `Option.getD` is not evaluated lazily, as the documentation says, because even after `macro_inline` the expression ```lean match opt, dflt with | some x, _ => x | none, e => e ``` still has the semantics of evaluating `dflt` when `opt` is `some x`.
This commit is contained in:
parent
e6c0484074
commit
178ab8ef2e
4 changed files with 20 additions and 6 deletions
|
|
@ -2213,9 +2213,10 @@ returns `a` if `opt = some a` and `dflt` otherwise.
|
|||
This function is `@[macro_inline]`, so `dflt` will not be evaluated unless
|
||||
`opt` turns out to be `none`.
|
||||
-/
|
||||
@[macro_inline] def Option.getD : Option α → α → α
|
||||
| some x, _ => x
|
||||
| none, e => e
|
||||
@[macro_inline] def Option.getD (opt : Option α) (dflt : α) : α :=
|
||||
match opt with
|
||||
| some x => x
|
||||
| none => dflt
|
||||
|
||||
/--
|
||||
Map a function over an `Option` by applying the function to the contained
|
||||
|
|
|
|||
12
tests/lean/optionGetD.lean
Normal file
12
tests/lean/optionGetD.lean
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import Lean.Data.HashMap
|
||||
|
||||
def test (m : Lean.HashMap Nat Nat) : IO (Nat × Nat) := do
|
||||
let start := 1
|
||||
let mut i := start
|
||||
let mut count := 0
|
||||
while i != 0 do
|
||||
i := (m.find? i).getD (panic! "key is not in the map")
|
||||
count := count + 1
|
||||
return (i, count)
|
||||
|
||||
#eval test (.ofList [(1,3),(3,2),(2,0)])
|
||||
1
tests/lean/optionGetD.lean.expected.out
Normal file
1
tests/lean/optionGetD.lean.expected.out
Normal file
|
|
@ -0,0 +1 @@
|
|||
(0, 3)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
42
|
||||
[Meta.debug] r: match x, 0 with
|
||||
| some x, x_1 => x
|
||||
| none, e => e
|
||||
[Meta.debug] r: match x with
|
||||
| some x => x
|
||||
| none => 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue