inductive Syntax | atom : String → Syntax | node : String → Array Syntax → Syntax instance coe1 : HasCoe String Syntax := ⟨Syntax.atom⟩ instance coe2 {α} : HasCoe (List α) (Array α) := ⟨List.toArray⟩ def ex7 : Syntax := /- We try to elaborate `["bla"]` with expected type `Array Syntax`. The expected type is "discarded" since we fail to unify `Array Syntax =?= List ?A` where `List ?A` is the resulting type for `List.cons` application before we process its children. Remark: the elaborator does **not** try to use coercions here. Even if it tried, it would fail since `List ?A` contains a meta-variable. Then, we elaborate `["bla"]` without an expected type and produce a term of type `List String`. Finally, we fail with a type mismatch between `List String` and `Array Nat`. We can make it work by using: ``` instance coe3 {α β} [HasCoe α β] : HasCoe (List α) (Array β) := ⟨fun xs => (xs.map (fun x => (coe x : β))).toArray⟩ ``` -/ Syntax.node "foo" ["bla"] def ex8 : Syntax := Syntax.node "foo" (List.toArray ["boo"]) -- Works def ex9 : Syntax := /- We need the type of `["boo"]` to be able to apply `.toArray`. So, we elaborate `["boo"]` first without expected type, and then obtain `Array String`, and then a type mismatch between `Array String` and `Array Syntax`. We can make it work by using: ``` instance coe3 {α β} [HasCoe α β] : HasCoe (Array α) (Array β) := ⟨fun xs => (xs.map (fun x => (coe x : β)))⟩ ``` But, the behavior is still confusing to users. -/ Syntax.node "foo" ["boo"].toArray