lean4-htt/src/Init/Dynamic.lean
Sebastian Ullrich 09a5b34931
feat: make private the default in module (#9044)
This PR adjusts the experimental module system to make `private` the
default visibility modifier in `module`s, introducing `public` as a new
modifier instead. `public section` can be used to revert the default for
an entire section, though this is more intended to ease gradual adoption
of the new semantics such as in `Init` (and soon `Std`) where they
should be replaced by a future decl-by-decl re-review of visibilities.
2025-06-28 16:30:53 +00:00

106 lines
3.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2022 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner
-/
module
prelude
public import Init.Core
public section
open Lean
-- Implementation detail of TypeName, since classes cannot be opaque
private opaque TypeNameData (α : Type u) : NonemptyType.{0} :=
⟨Name, inferInstance⟩
/--
Dynamic type name information.
Types with an instance of `TypeName` can be stored in an `Dynamic`.
The type class contains the declaration name of the type,
which must not have any universe parameters
and be of type `Sort ..` (i.e., monomorphic).
The preferred way to declare instances of this type is using the derive
handler, which will internally use the unsafe `TypeName.mk` function.
Morally, this is the same as:
```lean
class TypeName (α : Type) where unsafe mk ::
typeName : Name
```
-/
@[nospecialize]
class TypeName (α : Type u) where private mk' ::
private data : (TypeNameData α).type
instance : Nonempty (TypeName α) := (TypeNameData α).property.elim (⟨⟨·⟩⟩)
/--
Creates a `TypeName` instance.
For safety, it is required that the constant `typeName` is definitionally equal
to `α`.
-/
unsafe def TypeName.mk (α : Type u) (typeName : Name) : TypeName α :=
⟨unsafeCast typeName⟩
private unsafe def TypeName.typeNameImpl (α) [TypeName α] : Name :=
unsafeCast (@TypeName.data α _)
/--
Returns a declaration name of the type.
-/
@[implemented_by TypeName.typeNameImpl]
opaque TypeName.typeName (α) [TypeName α] : Name
private opaque DynamicPointed : NonemptyType.{0} :=
⟨Name × NonScalar, inferInstance⟩
/--
A type-tagged union that can store any type with a `TypeName` instance.
This is roughly equivalent to `(α : Type) × TypeName α × α`, but without the universe bump. Use
`Dynamic.mk` to inject a value into `Dynamic` from another type, and `Dynamic.get?` to extract a
value from `Dynamic` if it has some expected type.
-/
def Dynamic : Type := DynamicPointed.type
instance : Nonempty Dynamic := by exact DynamicPointed.property
private unsafe def Dynamic.typeNameImpl (any : Dynamic) : Name :=
(unsafeCast any : Name × NonScalar).1
/--
The name of the type of the value stored in the `Dynamic`.
-/
@[implemented_by Dynamic.typeNameImpl]
opaque Dynamic.typeName (any : Dynamic) : Name
private unsafe def Dynamic.get?Impl (α) (any : Dynamic) [TypeName α] : Option α :=
let ((typeName, obj) : Name × NonScalar) := unsafeCast any
if typeName == TypeName.typeName α then
some (unsafeCast obj)
else
none
/--
Retrieves the value stored in the `Dynamic`.
Returns `some a` if the value has the right type, and `none` otherwise.
-/
@[implemented_by Dynamic.get?Impl]
opaque Dynamic.get? (α) (any : Dynamic) [TypeName α] : Option α
private unsafe def Dynamic.mkImpl [TypeName α] (obj : α) : Dynamic :=
unsafeCast (TypeName.typeName α, (unsafeCast obj : NonScalar))
/--
Stores the provided value in a `Dynamic`.
Use `Dynamic.get? α` to retrieve it.
-/
@[implemented_by Dynamic.mkImpl]
opaque Dynamic.mk [TypeName α] (obj : α) : Dynamic