feat: add support for instance ... where
@Kha The fields are not mutually recursive yet, but it is good enough for writing examples in the manual. See new test
This commit is contained in:
parent
645c1034a0
commit
5884b9c19a
3 changed files with 65 additions and 2 deletions
|
|
@ -122,6 +122,44 @@ private partial def withFunLocalDecls {α} (headers : Array DefViewElabHeader) (
|
|||
k fvars
|
||||
loop 0 #[]
|
||||
|
||||
private def expandWhereDeclsAsStructInst (whereDecls : Syntax) : MacroM Syntax := do
|
||||
/- def whereDecls := parser! "where " >> many1Indent (group (optional «attributes» >> letDecl >> optional ";")) -/
|
||||
let letDecls ← whereDecls[1].getArgs.mapM fun stx => do
|
||||
unless stx[0].isNone do
|
||||
Macro.throwErrorAt stx "attributes are 'where' elements are currently not supported here"
|
||||
let mut letDecl := stx[1]
|
||||
if letDecl[0].isOfKind `Lean.Parser.Term.letPatDecl then
|
||||
Macro.throwErrorAt stx "patterns are not allowed here"
|
||||
if letDecl[0].getKind == `Lean.Parser.Term.letEqnsDecl then
|
||||
letDecl := letDecl.setArg 0 (← expandLetEqnsDecl letDecl[0])
|
||||
pure letDecl
|
||||
let structInstFields ← letDecls.mapM fun letDecl => do
|
||||
let letIdDecl := letDecl[0]
|
||||
let fieldId := letIdDecl[0]
|
||||
let mut val := letIdDecl[4]
|
||||
let optType := letIdDecl[2]
|
||||
let binders := letIdDecl[1]
|
||||
unless optType.isNone do
|
||||
let type := optType[0][1]
|
||||
val ← `(($val : $type))
|
||||
unless binders.isNone do
|
||||
let binders := binders.getArgs
|
||||
val ← `(fun $binders* => $val:term)
|
||||
val := val.copyInfo letIdDecl
|
||||
return Syntax.node `Lean.Parser.Term.structInstField #[
|
||||
fieldId, mkNullNode, mkAtomFrom fieldId ":=", val
|
||||
]
|
||||
let ref := whereDecls
|
||||
let structInst := Syntax.node `Lean.Parser.Term.structInst #[
|
||||
mkAtomFrom ref "{",
|
||||
mkNullNode,
|
||||
mkNullNode <| structInstFields.map fun field => mkNullNode #[field, mkNullNode],
|
||||
mkNullNode,
|
||||
mkNullNode,
|
||||
mkAtomFrom ref "}"
|
||||
]
|
||||
return structInst
|
||||
|
||||
/-
|
||||
Recall that
|
||||
```
|
||||
|
|
@ -131,7 +169,7 @@ withPosition $ fun pos =>
|
|||
sepBy1 matchAlt (checkColGe pos.column "alternatives must be indented" >> "|")
|
||||
def declValSimple := parser! " :=\n" >> termParser >> optional Term.whereDecls
|
||||
def declValEqns := parser! Term.matchAltsWhereDecls
|
||||
def declVal := declValSimple <|> declValEqns
|
||||
def declVal := declValSimple <|> declValEqns <|> Term.whereDecls
|
||||
```
|
||||
-/
|
||||
private def declValToTerm (declVal : Syntax) : MacroM Syntax :=
|
||||
|
|
@ -139,6 +177,8 @@ private def declValToTerm (declVal : Syntax) : MacroM Syntax :=
|
|||
return expandWhereDeclsOpt declVal declVal[2] declVal[1]
|
||||
else if declVal.isOfKind `Lean.Parser.Command.declValEqns then
|
||||
expandMatchAltsWhereDecls declVal declVal[0]
|
||||
else if declVal.isOfKind `Lean.Parser.Term.whereDecls then
|
||||
expandWhereDeclsAsStructInst declVal
|
||||
else
|
||||
Macro.throwErrorAt declVal "unexpected definition value"
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ def declSig := parser! many (ppSpace >> (Term.simpleBinderWithoutType <
|
|||
def optDeclSig := parser! many (ppSpace >> (Term.simpleBinderWithoutType <|> Term.bracketedBinder)) >> Term.optType
|
||||
def declValSimple := parser! " :=\n" >> termParser >> optional Term.whereDecls
|
||||
def declValEqns := parser! Term.matchAltsWhereDecls
|
||||
def declVal := declValSimple <|> declValEqns
|
||||
def declVal := declValSimple <|> declValEqns <|> Term.whereDecls
|
||||
def «abbrev» := parser! "abbrev " >> declId >> optDeclSig >> declVal
|
||||
def «def» := parser! "def " >> declId >> optDeclSig >> declVal
|
||||
def «theorem» := parser! "theorem " >> declId >> declSig >> declVal
|
||||
|
|
|
|||
23
tests/lean/run/instanceWhere.lean
Normal file
23
tests/lean/run/instanceWhere.lean
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
namespace Exp
|
||||
universes u v w
|
||||
|
||||
def StateT' (σ : Type u) (m : Type u → Type v) (α : Type u) : Type (max u v) :=
|
||||
σ → m (α × σ)
|
||||
|
||||
instance [Monad m] : Monad (StateT' σ m) where
|
||||
pure a := fun s => pure (a, s)
|
||||
|
||||
bind x f := fun s => do
|
||||
let (a, s) ← x s
|
||||
f a s
|
||||
|
||||
map f x := fun s => do
|
||||
let (a, s) ← x s
|
||||
pure (f a, s)
|
||||
|
||||
instance [ToString α] [ToString β] : ToString (Sum α β) where
|
||||
toString : Sum α β → String
|
||||
| Sum.inr a => "inl" ++ toString a
|
||||
| Sum.inl b => "inr" ++ toString b
|
||||
|
||||
end Exp
|
||||
Loading…
Add table
Reference in a new issue