| /- | |
| Copyright (c) 2021 Microsoft Corporation. All rights reserved. | |
| Released under Apache 2.0 license as described in the file LICENSE. | |
| Authors: Leonardo de Moura | |
| -/ | |
| prelude | |
| import Lean.MonadEnv | |
| namespace Lean | |
| structure LazyInitExtension (m : Type → Type) (α : Type) where | |
| ext : EnvExtension (Option α) | |
| fn : m α | |
| instance [Monad m] [Inhabited α] : Inhabited (LazyInitExtension m α) where | |
| default := { | |
| ext := default | |
| fn := pure default | |
| } | |
| /-- | |
| Register an environment extension for storing the result of `fn`. | |
| We initialize the extension with `none`, and `fn` is executed the | |
| first time `LazyInit.get` is executed. | |
| This kind of extension is useful for avoiding work duplication in | |
| scenarios where a thunk cannot be used because the computation depends | |
| on state from the `m` monad. For example, we may want to "cache" a collection | |
| of theorems as a `SimpLemmas` object. -/ | |
| def registerLazyInitExtension (fn : m α) : IO (LazyInitExtension m α) := do | |
| let ext ← registerEnvExtension (pure none) | |
| return { ext, fn } | |
| def LazyInitExtension.get [MonadEnv m] [Monad m] (init : LazyInitExtension m α) : m α := do | |
| match init.ext.getState (← getEnv) with | |
| | some a => return a | |
| | none => | |
| let a ← init.fn | |
| modifyEnv fun env => init.ext.setState env (some a) | |
| return a | |
| end Lean |