The semantics was weird. It seems Agda is also having problems with
it. Here is an example that demonstrates how weird the semantics is:
```lean
check (fun {β α} (a : α) (b : β) => (b, a) : {α : Type} → {β : Type} → (a : α) → (b : β) → β × α)
-- Same example using `def`
def f : {α : Type} → {β : Type} → α → β → β × α :=
fun {β : Type} {α : Type} (a : α) (b : β) => (b, a)
```
Both commands were being accepted before this commit. Note that it
flips `β` and `α`.
Here is an example that did not work before this commit and would
confuse users.
```lean
check
let id := fun {α} (a : α) => a;
id [id 1]
```
users would have to write
```lean
check
let id {α} (a : α) := a;
id [id 1]
```
@Kha The Delaborator.lean test broke and I "fixed" by removing the
`{}` from it, and copying `produced` over `expected`. Please make sure
it still makes sense.
55 lines
1.4 KiB
Text
55 lines
1.4 KiB
Text
import Init.Lean
|
||
open Lean
|
||
open Lean.Elab
|
||
open Lean.Elab.Term
|
||
|
||
def check (stx : TermElabM Syntax) (optionsPerPos : OptionsPerPos := {}) : TermElabM Unit := do
|
||
stx ← stx;
|
||
opts ← getOptions;
|
||
e ← elabTermAndSynthesize stx none <* throwErrorIfErrors;
|
||
stx' ← liftMetaM stx $ delab e opts optionsPerPos;
|
||
dbgTrace $ toString stx';
|
||
e' ← elabTermAndSynthesize stx' none <* throwErrorIfErrors;
|
||
unlessM (isDefEq stx e e') $
|
||
throwError stx "failed to round-trip"
|
||
|
||
-- #eval check `(?m) -- fails round-trip
|
||
|
||
#eval check `(Sort)
|
||
#eval check `(Type)
|
||
#eval check `(Type 0)
|
||
#eval check `(Type 1)
|
||
-- can't add a new universe variable inside a term...
|
||
#eval check `(Type _)
|
||
#eval check `(Type (_ + 2))
|
||
|
||
#eval check `(Nat)
|
||
#eval check `(List Nat)
|
||
#eval check `(id Nat)
|
||
section
|
||
set_option pp.explicit true
|
||
#eval check `(List Nat)
|
||
#eval check `(id Nat)
|
||
end
|
||
section
|
||
set_option pp.universes true
|
||
#eval check `(List Nat)
|
||
#eval check `(id Nat)
|
||
end
|
||
#eval check `(id (id Nat)) (RBMap.empty.insert 4 $ KVMap.empty.insert `pp.explicit true)
|
||
|
||
#eval check `(fun (a : Nat) => a)
|
||
#eval check `(fun (a b : Nat) => a)
|
||
#eval check `(fun (a : Nat) (b : Bool) => a)
|
||
#eval check `(@(fun (a b : Nat) => a))
|
||
#eval check `(@(fun α (s : HasToString α) => true))
|
||
|
||
-- TODO: hide `ofNat`
|
||
#eval check `(0)
|
||
#eval check `(1)
|
||
#eval check `(42)
|
||
#eval check `("hi")
|
||
|
||
#eval check `((1,2).fst)
|
||
|
||
#eval check `(1 < 2 || true)
|