3.6 On understanding the propagation of the expected type
3.6.2 Analysis of a Propagation Root
TheProprules that realize the propagation judgment (Figure 3.18) identify 6 type inference rules that can serve as a Propagation Root for a prototype. The typing decisions that infer the fresh prototype Pf in those rules may differ significantly. That is why in this section we define aslicesPtRootfunction that takes any Propagation Root and finds the source of the fresh prototype based on the typing decisions of the formal type inference rules.
TheslicesPtRootpartial function, of type ( (P,Γ wE : T ),Θ ) → ν3takes an inference judg-
ment representing the Propagation Root of some prototype, say P, and a TypeFocus, sayΘ, such that (Θ, WFPf) andΘ(Pf)=inlP. The function returns a sequence of Typing Slices
3.6. On understanding the propagation of the expected type
explaining the source of the prototype P.
TheslicesPtRootfunction is realized through a set of rule-specific functions defined in Fig- ure 3.20. Each type inference rule is considered separately, as indicated through the rule sub- script in the function nameslicesPtRootrule. For clarity, Figure 3.20 highlights the position
of Pf, that is inference rule-specific, with gray boxes.
Having presented the purpose of theslicesPtRootfunction we will now delve into the de- tails of each of the type inference rule of Colored Local Type Inference that can serve as the Propagation Root for some prototype.
The(app)type inference rule
TheslicesPtRoot(app) function finds the source of the highlighted prototype ([?/a] S) used
in the inference of the type of the argument. The type inference rule states that the non- wildcard elements of the used prototype can only come from the inferred type of the func- tion. Therefore in order to locate the source of the prototype we delegate to the established TypeFocus-based analysis from Section 3.5.3.
We recall that in order to trigger the TypeFocus-based analysis we have to provide a type se- lection that is well-formed type selection with respect to the inferred type of the function. The TypeFocus used in theslicesPtRoot(app)function,φfun-param::Θ, satisfies that condi- tion because: (Θ, WF[?/
a] S) (from the precondition of theslicesPtRootfunction) implies
(Θ,fv([?/
a] S)WF[?/a] S), and, by Lemma 3.8, (Θ,a WFS) and (φfun-param::Θ,a WF∀a.S → T ). The(appt p)type inference rule
TheslicesPtRoot(appt p)function analyses the inference of a type of a function application using a similar approach as in the case of the(app)rule, except that it also has to take into account the presence of the explicit type arguments.
By a similar argument as in the previous case,φfun-param::Θ defines a type selection well- formed with respect to the inferred type of the function because: (Θ, WF[R/
a] S) (from the
precondition of theslicesPtRootfunction) implies (Θ,fv([R/a] S)WF[R/a] S), and, by Lemma
3.8, (φfun-param::Θ,a WFS), and (φfun-param::Θ,a WF∀a.S → T ).
In contrast to the function application with elided type arguments ([?/
a] S), we have to take
into account the possibility that the fresh prototype could involve one of the explicit type arguments ([R/a] S). The reconstructed type selection is sufficient to distinguish between the
two possible sources of the prototype:
• (φfun-param::Θ)(∀a.S → T )tpe= a and a ∈ a:
The extraction of the type variable a implies that the explicit type argument is the source of the prototype represented by theΘ TypeFocus. Since type arguments defines
Chapter 3. Guided-analysis for type derivation trees
FUNCTIONslicesPtRoot(app)((app),Θ ) =
(app) ?,Γ,wF :∀a.S → T [?/ a] S ,Γ wE : S a S<: S ⇒ C1 aT<: P ⇒ C2 P,Γ wF (E ) :σ C1∪C2,TT P 1 SLICES((?,Γ wF :∀a.S → T ), (φfun-param::Θ) )
FUNCTIONslicesPtRoot(app⊥)((app⊥),Θ ) = (app⊥)?,Γ,
wF :⊥ ,Γ wE : S P,Γ wF (E ) :⊥ P
1 SLICES((?,Γ wF :⊥), [ ])
FUNCTIONslicesPtRoot(appt p)
(appt p),Θ = (appt p) ?,Γ,wF :∀a.S → T [R/a] S ,Γ wE : [R/a] S P,Γ wFR(E ) : [R/a] T P 1 2 3 Θcont= φ fun-param::Θ IF(is-tvar(Θcont(S) tpe, a))
νTVAR, (?,Γ wF :∀a.S → T ), Θcont
ELSE SLICES((?,Γ wF :∀a.S → T ), Θcont)
FUNCTIONslicesPtRoot(appt p,⊥)(appt p,⊥),Θ= (appt p,⊥)?,Γ,
wF :⊥ ,Γ wE : S P,Γ wFR(E ) :⊥ P
1 SLICES((?,Γ wF : ⊥), [ ] )
FUNCTIONslicesPtRoot(sel)((sel),Θ ) = (sel) {x : P } ,Γ, wF : {x : T } P,Γ wF.x : T 1 2 IF(head(Θ) == [φselx]) 〈νPT, (P,Γ wF.x : T ),tail(Θ)〉 ELSE 〈νTSIG, ({x : P },Γ wF : {x : T }),Θ〉 FUNCTIONslicesPtRoot(rec)((rec),Θ ) =
(rec)(P1,Γ
wF
1: T1) ... (Pm,Γ wFm: Tm) ( , Γ wFm+1: Tm+1) ... ( , Γ wFn: Tn)
{x1: P1, ..., xm: Pm},Γ w{x1= F1, ..., xn= Fn}: {x1: T1, ..., xm: Tm}
1 〈νPT, ({x1: P1, ..., xm: Pm},Γ w{x1= F1, ..., xn= Fn}: {x1: T1, ..., xm: Tm}), [ ]〉
Figure 3.20: Algorithm for finding the source of the fresh prototype Pf r esh that is in- troduced in the Propagation Root judgments. The algorithm is realized through the slicesPtRoot function of type ( (P,Γ wE : T ),Θ ) → ν3 which analyzes typing deci-
sions of every type inference rule that can serve as a Propagation Root. The gray boxes highlight the position of the fresh Pf prototype source of which the function explains.
3.6. On understanding the propagation of the expected type
an instantiation of the type variable the discovery is represented by the Type Variable Typing Slice.
• (φfun-param::Θ)(∀a.S → T )tpe= a and a ∈ a:
None of the type variables, and, in consequence, none of the type arguments are the source of the selected part of the prototype. We will explain the source of the prototype by delegating to the generic TypeFocus-based analysis.
The(app⊥)and(appt p,⊥)type inference rules
The(app⊥)and(appt p,⊥)type inference rules propagate prototype as a consequence of
the inferred type of the function, ⊥. Consequently, the correspondingslicesPtRoot(app⊥) and slicesPtRoot(appt p,⊥) functions analyze the indirect relation between the typing deci- sions by delegating to the TypeFocus-basedSLICESalgorithm. Since both and ⊥ represent
types with no inner type components, we simplify the type selection to an identity TypeFocus, [ ], without compromising the correctness of the algorithm.
The(rec)type inference rule
The source of the highlighted prototype in ruleslicesPtRoot(rec)cannot be inferred from other premises of the (rec)rule. By returning the Prototype Typing Slice we explain the indirect source of the prototype - the record type prototype which did not define the expected type for any of the members xkwhere m< k ≤ n.
The(sel)type inference rule
The {x : T } prototype is used to infer the type of the record term in the(sel)type inference rule. Indirectly, the source of the fresh prototype lies in the record selection term. Rather than always returning the record selection term as an explanation of the fresh prototype, the algorithm takes into account the type selection in order to provide a correct explanation of the part of the fresh prototype.
For example, a simple inference judgment (I nt→ ?, w{x= fun(y)y}.x : I nt→ Int) uses prototype I nt→ ? to infer the type of thefun(y)y abstraction. If the analysis seeks to explain the source of only a fragment of the given prototype ( Int → ?), then the Int prototype is a result of a prototype propagation and the decisions of the .x record selection are irrelevant. We use the properties of the type selection in order to distinguish between the two scenarios. From the precondition of theslicesPtRootfunction (Θ, WF{x : P }) and by the Canonical Forms lemma (Lemma 3.5)head(Θ) is either [ ] or [φselx]. Ifhead(Θ) == [φselx] for any x then
the record selection operations is irrelevant for explaining the source of the prototype and it has been inherited from the context (as explained by the Prototype Typing Slice in line 1). If head(Θ) = [ ] then Θ = [ ] (by Lemma D.2) and the source of the prototype lies in the record selection term, as explained by the Type Signature Typing Slice.
Chapter 3. Guided-analysis for type derivation trees
Final remarks
TheslicesPtRootfunction has to handle every type inference rule that may serve as a Prop- agation Root for some prototype. The essence of every case lies in identifying a link between the fresh prototype and a typing decision that introduced it in the formal type inference rule. TheslicesPtRootfunctions are generic in a sense that the whole information about the part of the fresh prototype, source of which we seek to explain, is encapsulated in the TypeFocus abstraction and the well-formedness property is maintained based on the formal specifica- tion of the type inference rules.