42 lines
1.3 KiB
Text
42 lines
1.3 KiB
Text
/-
|
||
Copyright (c) 2022 Mac Malone. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Mac Malone
|
||
-/
|
||
import Lean.Parser.Command
|
||
|
||
open Lean
|
||
namespace Lake
|
||
|
||
class DynamicType {α : Type u} (Δ : α → Type v) (a : α) (β : outParam $ Type v) : Prop where
|
||
eq_dynamic_type : Δ a = β
|
||
|
||
export DynamicType (eq_dynamic_type)
|
||
|
||
@[inline] def toDynamic (a : α) [DynamicType Δ a β] (b : β) : Δ a :=
|
||
cast eq_dynamic_type.symm b
|
||
|
||
@[inline] def ofDynamic (a : α) [DynamicType Δ a β] (b : Δ a) : β :=
|
||
cast eq_dynamic_type b
|
||
|
||
/--
|
||
The syntax:
|
||
|
||
```lean
|
||
dynamic_data foo : Data 0 := Nat
|
||
```
|
||
|
||
Declares a new alternative for the dynamic `Data` type via the
|
||
production of an axiom `foo : Data 0 = Nat` and an instance of `DynamicType`
|
||
that uses this axiom for key `0`.
|
||
-/
|
||
scoped macro (name := dynamicDataDecl) doc?:optional(Parser.Command.docComment)
|
||
"dynamic_data " id:ident " : " dty:ident key:term " := " ty:term : command => do
|
||
let tid := extractMacroScopes dty.getId |>.name
|
||
if let (tid, _) :: _ ← Macro.resolveGlobalName tid then
|
||
let app := Syntax.mkApp dty #[key]
|
||
let axm := mkIdentFrom dty <| `_root_ ++ tid ++ id.getId
|
||
`($[$doc?]? @[simp] axiom $axm : $app = $ty
|
||
instance : DynamicType $dty $key $ty := ⟨$axm⟩)
|
||
else
|
||
Macro.throwErrorAt dty s!"unknown identifier '{tid}'"
|