diff options
author | Hans Bolinder <[email protected]> | 2016-01-20 09:54:00 +0100 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2016-01-20 10:26:03 +0100 |
commit | 34e02fed50bbaa2af7b1828968b6ec02a54e98c8 (patch) | |
tree | ca255b4cf41ff369a9776c2cf1ddd01a0c327c48 /erts/doc | |
parent | b21f71c1bb79d3979505ad6ad1e496472b38c6b9 (diff) | |
download | otp-34e02fed50bbaa2af7b1828968b6ec02a54e98c8.tar.gz otp-34e02fed50bbaa2af7b1828968b6ec02a54e98c8.tar.bz2 otp-34e02fed50bbaa2af7b1828968b6ec02a54e98c8.zip |
erts: Improve the documentation of the abstract format
Diffstat (limited to 'erts/doc')
-rw-r--r-- | erts/doc/src/absform.xml | 240 |
1 files changed, 131 insertions, 109 deletions
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml index 1c0c3e1319..3f47b3061b 100644 --- a/erts/doc/src/absform.xml +++ b/erts/doc/src/absform.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2001</year><year>2015</year> + <year>2001</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -80,12 +80,15 @@ Rep(F) = <c>{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}</c>.</item> <item>If F is an attribute <c>-export_type([Type_1/A_1, ..., Type_k/A_k])</c>, then Rep(F) = <c>{attribute,LINE,export_type,[{Type_1,A_1}, ..., {Type_k,A_k}]}</c>.</item> + <item>If F is an attribute <c>-optional_callbacks([Fun_1/A_1, ..., Fun_k/A_k])</c>, then + Rep(F) = <c>{attribute,LINE,optional_callbacks,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}</c>.</item> <item>If F is an attribute <c>-compile(Options)</c>, then Rep(F) = <c>{attribute,LINE,compile,Options}</c>.</item> <item>If F is an attribute <c>-file(File,Line)</c>, then Rep(F) = <c>{attribute,LINE,file,{File,Line}}</c>.</item> <item>If F is a record declaration - <c>-record(Name,{V_1, ..., V_k})</c>, then Rep(F) = + <c>-record(Name,{V_1, ..., V_k})</c>, + where each <c>V_i</c> is a record field, then Rep(F) = <c>{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}</c>. For Rep(V), see below.</item> <item>If F is a type declaration @@ -173,12 +176,12 @@ <section> <title>Patterns</title> - <p>If <c>Ps</c> is a sequence of patterns <c>P_1, ..., P_k</c>, then + <p>If Ps is a sequence of patterns <c>P_1, ..., P_k</c>, then Rep(Ps) = <c>[Rep(P_1), ..., Rep(P_k)]</c>. Such sequences occur as the list of arguments to a function or fun.</p> <p>Individual patterns are represented as follows:</p> <list type="bulleted"> - <item>If P is an atomic literal L, then Rep(P) = Rep(L).</item> + <item>If P is an atomic literal <c>L</c>, then Rep(P) = Rep(L).</item> <item>If P is a compound pattern <c>P_1 = P_2</c>, then Rep(P) = <c>{match,LINE,Rep(P_1),Rep(P_2)}</c>.</item> <item>If P is a variable pattern <c>V</c>, then @@ -211,6 +214,10 @@ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}</c>.</item> <item>If P is <c>#Name.Field</c>, then Rep(P) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item> + <item>If P is a map pattern <c>#{A_1, ..., A_k}</c>, where each + <c>A_i</c> is an association <c>P_i_1 := P_i_2</c>, then Rep(P) = + <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. For Rep(A), see + below.</item> <item>If P is <c>( P_0 )</c>, then Rep(P) = <c>Rep(P_0)</c>, that is, patterns cannot be distinguished from their bodies.</item> @@ -221,11 +228,11 @@ <section> <title>Expressions</title> - <p>A body B is a sequence of expressions <c>E_1, ..., E_k</c>, and - Rep(B) = <c>[Rep(E_1), ..., Rep(E_k)]</c>.</p> + <p>A body B is a nonempty sequence of expressions <c>E_1, ..., E_k</c>, + and Rep(B) = <c>[Rep(E_1), ..., Rep(E_k)]</c>.</p> <p>An expression E is one of the following alternatives:</p> <list type="bulleted"> - <item>If P is an atomic literal <c>L</c>, then Rep(P) = Rep(L).</item> + <item>If E is an atomic literal <c>L</c>, then Rep(E) = Rep(L).</item> <item>If E is <c>P = E_0</c>, then Rep(E) = <c>{match,LINE,Rep(P),Rep(E_0)}</c>.</item> <item>If E is a variable <c>V</c>, then Rep(E) = <c>{var,LINE,A}</c>, @@ -256,14 +263,16 @@ Rep(E) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item> <item>If E is <c>E_0#Name.Field</c>, then Rep(E) = <c>{record_field,LINE,Rep(E_0),Name,Rep(Field)}</c>.</item> - <item>If E is <c>#{W_1, ..., W_k}</c> where each - <c>W_i</c> is a map assoc or exact field, then Rep(E) = - <c>{map,LINE,[Rep(W_1), ..., Rep(W_k)]}</c>. For Rep(W), see + <item>If E is a map creation <c>#{A_1, ..., A_k}</c>, + where each <c>A_i</c> is an association <c>E_i_1 => E_i_2</c> + or <c>E_i_1 := E_i_2</c>, then Rep(E) = + <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. For Rep(A), see below.</item> - <item>If E is <c>E_0#{W_1, ..., W_k}</c> where - <c>W_i</c> is a map assoc or exact field, then Rep(E) = - <c>{map,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>. - For Rep(W), see below.</item> + <item>If E is a map update <c>E_0#{A_1, ..., A_k}</c>, + where each <c>A_i</c> is an association <c>E_i_1 => E_i_2</c> + or <c>E_i_1 := E_i_2</c>, then Rep(E) = + <c>{map,LINE,Rep(E_0),[Rep(A_1), ..., Rep(A_k)]}</c>. + For Rep(A), see below.</item> <item>If E is <c>catch E_0</c>, then Rep(E) = <c>{'catch',LINE,Rep(E_0)}</c>.</item> <item>If E is <c>E_0(E_1, ..., E_k)</c>, then @@ -271,15 +280,15 @@ <item>If E is <c>E_m:E_0(E_1, ..., E_k)</c>, then Rep(E) = <c>{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ..., Rep(E_k)]}</c>. </item> - <item>If E is a list comprehension <c>[E_0 || W_1, ..., W_k]</c>, - where each <c>W_i</c> is a generator or a filter, then Rep(E) = - <c>{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>. For Rep(W), see + <item>If E is a list comprehension <c>[E_0 || Q_1, ..., Q_k]</c>, + where each <c>Q_i</c> is a qualifier, then Rep(E) = + <c>{lc,LINE,Rep(E_0),[Rep(Q_1), ..., Rep(Q_k)]}</c>. For Rep(Q), see below.</item> <item>If E is a binary comprehension - <c><<E_0 || W_1, ..., W_k>></c>, - where each <c>W_i</c> is a generator or a filter, then - Rep(E) = <c>{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>. - For Rep(W), see below.</item> + <c><<E_0 || Q_1, ..., Q_k>></c>, + where each <c>Q_i</c> is a qualifier, then + Rep(E) = <c>{bc,LINE,Rep(E_0),[Rep(Q_1), ..., Rep(Q_k)]}</c>. + For Rep(Q), see below.</item> <item>If E is <c>begin B end</c>, where <c>B</c> is a body, then Rep(E) = <c>{block,LINE,Rep(B)}</c>.</item> <item>If E is <c>if Ic_1 ; ... ; Ic_k end</c>, @@ -311,7 +320,7 @@ <c>{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}</c>.</item> <item>If E is <c>try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n after A end</c>, where <c>B</c> and <c>A</c> are a bodies, - each <c>Cc_i</c> is a case clause and + each <c>Cc_i</c> is a case clause, and each <c>Tc_j</c> is a catch clause then Rep(E) = <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],Rep(A)}</c>.</item> @@ -328,10 +337,10 @@ <c>{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}</c>. (Before the R15 release: Rep(E) = <c>{'fun',LINE,{function,Module,Name,Arity}}</c>.)</item> - <item>If E is <c>fun Fc_1 ; ... ; Fc_k end</c> + <item>If E is <c>fun Fc_1 ; ... ; Fc_k end</c>, where each <c>Fc_i</c> is a function clause then Rep(E) = <c>{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}</c>.</item> - <item>If E is <c>fun Name Fc_1 ; ... ; Name Fc_k end</c> + <item>If E is <c>fun Name Fc_1 ; ... ; Name Fc_k end</c>, where <c>Name</c> is a variable and each <c>Fc_i</c> is a function clause then Rep(E) = <c>{named_fun,LINE,Name,[Rep(Fc_1), ..., Rep(Fc_k)]}</c>. @@ -342,46 +351,43 @@ </list> <section> - <title>Generators and Filters</title> - <p>When W is a generator or a filter (in the body of a list or - binary comprehension), then:</p> + <title>Qualifiers</title> + <p>A qualifier Q is one of the following alternatives:</p> <list type="bulleted"> - <item>If W is a generator <c>P <- E</c>, where <c>P</c> is + <item>If Q is a generator <c>P <- E</c>, where <c>P</c> is a pattern and <c>E</c> is an expression, then - Rep(W) = <c>{generate,LINE,Rep(P),Rep(E)}</c>.</item> - <item>If W is a generator <c>P <= E</c>, where <c>P</c> is + Rep(Q) = <c>{generate,LINE,Rep(P),Rep(E)}</c>.</item> + <item>If Q is a generator <c>P <= E</c>, where <c>P</c> is a pattern and <c>E</c> is an expression, then - Rep(W) = <c>{b_generate,LINE,Rep(P),Rep(E)}</c>.</item> - <item>If W is a filter <c>E</c>, which is an expression, then - Rep(W) = <c>Rep(E)</c>.</item> + Rep(Q) = <c>{b_generate,LINE,Rep(P),Rep(E)}</c>.</item> + <item>If Q is a filter <c>E</c>, where <c>E</c> is an expression, then + Rep(Q) = <c>Rep(E)</c>.</item> </list> </section> <section> <title>Binary Element Type Specifiers</title> <p>A type specifier list TSL for a binary element is a sequence of type - specifiers <c>TS_1 - ... - TS_k</c>. + specifiers <c>TS_1 - ... - TS_k</c>, and Rep(TSL) = <c>[Rep(TS_1), ..., Rep(TS_k)]</c>.</p> - <p>When TS is a type specifier for a binary element, then:</p> <list type="bulleted"> - <item>If TS is an atom <c>A</c>, then Rep(TS) = <c>A</c>.</item> - <item>If TS is a couple <c>A:Value</c> where <c>A</c> is an atom - and <c>Value</c> is an integer, then Rep(TS) = - <c>{A,Value}</c>.</item> + <item>If TS is a type specifier <c>A</c>, where <c>A</c> is an atom, + then Rep(TS) = <c>A</c>.</item> + <item>If TS is a type specifier <c>A:Value</c>, + where <c>A</c> is an atom and <c>Value</c> is an integer, + then Rep(TS) = <c>{A,Value}</c>.</item> </list> </section> <section> - <title>Map Assoc and Exact Fields</title> - <p>When W is an assoc or exact field (in the body of a map), then:</p> + <title>Associations</title> + <p>An association A is one of the following alternatives:</p> <list type="bulleted"> - <item>If W is an assoc field <c>K => V</c>, where - <c>K</c> and <c>V</c> are both expressions, - then Rep(W) = <c>{map_field_assoc,LINE,Rep(K),Rep(V)}</c>. + <item>If A is an association <c>K => V</c>, + then Rep(A) = <c>{map_field_assoc,LINE,Rep(K),Rep(V)}</c>. </item> - <item>If W is an exact field <c>K := V</c>, where - <c>K</c> and <c>V</c> are both expressions, - then Rep(W) = <c>{map_field_exact,LINE,Rep(K),Rep(V)}</c>. + <item>If A is an association <c>K := V</c>, + then Rep(A) = <c>{map_field_exact,LINE,Rep(K),Rep(V)}</c>. </item> </list> </section> @@ -393,37 +399,37 @@ and catch clauses.</p> <p>A clause <c>C</c> is one of the following alternatives:</p> <list type="bulleted"> - <item>If C is a function clause <c>( Ps ) -> B</c> + <item>If C is a function clause <c>( Ps ) -> B</c>, where <c>Ps</c> is a pattern sequence and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,Rep(Ps),[],Rep(B)}</c>.</item> - <item>If C is a function clause <c>( Ps ) when Gs -> B</c> + <item>If C is a function clause <c>( Ps ) when Gs -> B</c>, where <c>Ps</c> is a pattern sequence, <c>Gs</c> is a guard sequence and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}</c>.</item> - <item>If C is an if clause <c>Gs -> B</c> + <item>If C is an if clause <c>Gs -> B</c>, where <c>Gs</c> is a guard sequence and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[],Rep(Gs),Rep(B)}</c>.</item> - <item>If C is a case clause <c>P -> B</c> + <item>If C is a case clause <c>P -> B</c>, where <c>P</c> is a pattern and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[Rep(P)],[],Rep(B)}</c>.</item> - <item>If C is a case clause <c>P when Gs -> B</c> + <item>If C is a case clause <c>P when Gs -> B</c>, where <c>P</c> is a pattern, <c>Gs</c> is a guard sequence and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}</c>.</item> - <item>If C is a catch clause <c>P -> B</c> + <item>If C is a catch clause <c>P -> B</c>, where <c>P</c> is a pattern and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}</c>.</item> - <item>If C is a catch clause <c>X : P -> B</c> + <item>If C is a catch clause <c>X : P -> B</c>, where <c>X</c> is an atomic literal or a variable pattern, - <c>P</c> is a pattern and <c>B</c> is a body, then + <c>P</c> is a pattern, and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],[],Rep(B)}</c>.</item> - <item>If C is a catch clause <c>P when Gs -> B</c> - where <c>P</c> is a pattern, <c>Gs</c> is a guard sequence + <item>If C is a catch clause <c>P when Gs -> B</c>, + where <c>P</c> is a pattern, <c>Gs</c> is a guard sequence, and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}</c>.</item> - <item>If C is a catch clause <c>X : P when Gs -> B</c> + <item>If C is a catch clause <c>X : P when Gs -> B</c>, where <c>X</c> is an atomic literal or a variable pattern, - <c>P</c> is a pattern, <c>Gs</c> is a guard sequence + <c>P</c> is a pattern, <c>Gs</c> is a guard sequence, and <c>B</c> is a body, then Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}</c>.</item> </list> @@ -439,7 +445,7 @@ <c>[Rep(Gt_1), ..., Rep(Gt_k)]</c>.</p> <p>A guard test <c>Gt</c> is one of the following alternatives:</p> <list type="bulleted"> - <item>If Gt is an atomic literal L, then Rep(Gt) = Rep(L).</item> + <item>If Gt is an atomic literal <c>L</c>, then Rep(Gt) = Rep(L).</item> <item>If Gt is a variable pattern <c>V</c>, then Rep(Gt) = <c>{var,LINE,A}</c>, where A is an atom with a printname consisting of the same characters as <c>V</c>.</item> @@ -467,15 +473,21 @@ Rep(Gt) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item> <item>If Gt is <c>Gt_0#Name.Field</c>, then Rep(Gt) = <c>{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}</c>.</item> + <item>If Gt is a map creation <c>#{A_1, ..., A_k}</c>, + where each <c>A_i</c> is an association <c>Gt_i_1 => Gt_i_2</c> + or <c>Gt_i_1 := Gt_i_2</c>, then Rep(Gt) = + <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. For Rep(A), see + above.</item> + <item>If Gt is a map update <c>Gt_0#{A_1, ..., A_k}</c>, where each + <c>A_i</c> is an association <c>Gt_i_1 => Gt_i_2</c> + or <c>Gt_i_1 := Gt_i_2</c>, then Rep(Gt) = + <c>{map,LINE,Rep(Gt_0),[Rep(A_1), ..., Rep(A_k)]}</c>. + For Rep(A), see above.</item> <item>If Gt is <c>A(Gt_1, ..., Gt_k)</c>, where <c>A</c> is an atom, then Rep(Gt) = <c>{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item> <item>If Gt is <c>A_m:A(Gt_1, ..., Gt_k)</c>, where <c>A_m</c> is the atom <c>erlang</c> and <c>A</c> is an atom or an operator, then Rep(Gt) = <c>{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item> - <item>If Gt is <c>{A_m,A}(Gt_1, ..., Gt_k)</c>, where <c>A_m</c> is - the atom <c>erlang</c> and <c>A</c> is an atom or an operator, then - Rep(Gt) = <c>{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}</c>. - </item> <item>If Gt is <c>( Gt_0 )</c>, then Rep(Gt) = <c>Rep(Gt_0)</c>, that is, parenthesized guard tests cannot be distinguished from their bodies.</item> @@ -487,21 +499,20 @@ <section> <title>Types</title> <list type="bulleted"> - <item>If T is an annotated type <c>Anno :: Type</c>, - where <c>Anno</c> is a variable and - <c>Type</c> is a type, then Rep(T) = - <c>{ann_type,LINE,[Rep(Anno),Rep(Type)]}</c>.</item> + <item>If T is an annotated type <c>A :: T_0</c>, + where <c>A</c> is a variable, then Rep(T) = + <c>{ann_type,LINE,[Rep(A),Rep(T_0)]}</c>.</item> <item>If T is an atom or integer literal L, then Rep(T) = Rep(L). </item> - <item>If T is <c>L Op R</c>, - where <c>Op</c> is a binary operator and <c>L</c> and <c>R</c> - are types (this is an occurrence of an expression that can be - evaluated to an integer at compile time), then - Rep(T) = <c>{op,LINE,Op,Rep(L),Rep(R)}</c>.</item> - <item>If T is <c>Op A</c>, where <c>Op</c> is a - unary operator and <c>A</c> is a type (this is an occurrence of + <item>If T is an operator type <c>T_1 Op T_2</c>, + where <c>Op</c> is a binary operator (this is an occurrence of + an expression that can be evaluated to an integer at compile + time), then + Rep(T) = <c>{op,LINE,Op,Rep(T_1),Rep(T_2)}</c>.</item> + <item>If T is an operator type <c>Op T_0</c>, where <c>Op</c> is a + unary operator (this is an occurrence of an expression that can be evaluated to an integer at compile time), - then Rep(T) = <c>{op,LINE,Op,Rep(A)}</c>.</item> + then Rep(T) = <c>{op,LINE,Op,Rep(T_0)}</c>.</item> <item>If T is a bitstring type <c><<_:M,_:_*N>></c>, where <c>M</c> and <c>N</c> are singleton integer types, then Rep(T) = <c>{type,LINE,binary,[Rep(M),Rep(N)]}</c>.</item> @@ -509,53 +520,44 @@ <c>{type,Line,nil,[]}</c>.</item> <item>If T is a fun type <c>fun()</c>, then Rep(T) = <c>{type,LINE,'fun',[]}</c>.</item> - <item>If T is a fun type <c>fun((...) -> B)</c>, - where <c>B</c> is a type, then - Rep(T) = <c>{type,LINE,'fun',[{type,LINE,any},Rep(B)]}</c>. + <item>If T is a fun type <c>fun((...) -> T_0)</c>, then + Rep(T) = <c>{type,LINE,'fun',[{type,LINE,any},Rep(T_0)]}</c>. </item> <item>If T is a fun type <c>fun(Ft)</c>, where <c>Ft</c> is a function type, - then Rep(T) = <c>Rep(Ft)</c>.</item> + then Rep(T) = <c>Rep(Ft)</c>. For Rep(Ft), see below.</item> <item>If T is an integer range type <c>L .. H</c>, where <c>L</c> and <c>H</c> are singleton integer types, then Rep(T) = <c>{type,LINE,range,[Rep(L),Rep(H)]}</c>.</item> <item>If T is a map type <c>map()</c>, then Rep(T) = <c>{type,LINE,map,any}</c>.</item> - <item>If T is a map type <c>#{P_1, ..., P_k}</c>, where each - <c>P_i</c> is a map pair type, then Rep(T) = - <c>{type,LINE,map,[Rep(P_1), ..., Rep(P_k)]}</c>.</item> - <item>If T is a map pair type <c>K => V</c>, where - <c>K</c> and <c>V</c> are types, then Rep(T) = - <c>{type,LINE,map_field_assoc,[Rep(K),Rep(V)]}</c>.</item> - <item>If T is a predefined (or built-in) type <c>N(A_1, ..., A_k)</c>, - where each <c>A_i</c> is a type, then Rep(T) = - <c>{type,LINE,N,[Rep(A_1), ..., Rep(A_k)]}</c>.</item> + <item>If T is a map type <c>#{A_1, ..., A_k}</c>, where each + <c>A_i</c> is an association type, then Rep(T) = + <c>{type,LINE,map,[Rep(A_1), ..., Rep(A_k)]}</c>. + For Rep(A), see below.</item> + <item>If T is a predefined (or built-in) type <c>N(T_1, ..., T_k)</c>, + then Rep(T) = + <c>{type,LINE,N,[Rep(T_1), ..., Rep(T_k)]}</c>.</item> <item>If T is a record type <c>#Name{F_1, ..., F_k}</c>, where each <c>F_i</c> is a record field type, then Rep(T) = <c>{type,LINE,record,[Rep(Name),Rep(F_1), ..., Rep(F_k)]}</c>. - </item> - <item>If T is a record field type <c>Name :: Type</c>, - where <c>Type</c> is a type, then Rep(T) = - <c>{type,LINE,field_type,[Rep(Name),Rep(Type)]}</c>.</item> - <item>If T is a remote type <c>M:N(A_1, ..., A_k)</c>, where - each <c>A_i</c> is a type, then Rep(T) = - <c>{remote_type,LINE,[Rep(M),Rep(N),[Rep(A_1), ..., Rep(A_k)]]}</c>. + For Rep(F), see below.</item> + <item>If T is a remote type <c>M:N(T_1, ..., T_k)</c>, then Rep(T) = + <c>{remote_type,LINE,[Rep(M),Rep(N),[Rep(T_1), ..., Rep(T_k)]]}</c>. </item> <item>If T is a tuple type <c>tuple()</c>, then Rep(T) = <c>{type,LINE,tuple,any}</c>.</item> - <item>If T is a tuple type <c>{A_1, ..., A_k}</c>, where - each <c>A_i</c> is a type, then Rep(T) = - <c>{type,LINE,tuple,[Rep(A_1), ..., Rep(A_k)]}</c>.</item> - <item>If T is a type union <c>T_1 | ... | T_k</c>, - where each <c>T_i</c> is a type, then Rep(T) = + <item>If T is a tuple type <c>{T_1, ..., T_k}</c>, then Rep(T) = + <c>{type,LINE,tuple,[Rep(T_1), ..., Rep(T_k)]}</c>.</item> + <item>If T is a type union <c>T_1 | ... | T_k</c>, then Rep(T) = <c>{type,LINE,union,[Rep(T_1), ..., Rep(T_k)]}</c>.</item> <item>If T is a type variable <c>V</c>, then Rep(T) = <c>{var,LINE,A}</c>, where <c>A</c> is an atom with a printname consisting of the same characters as <c>V</c>. A type variable is any variable except underscore (<c>_</c>).</item> - <item>If T is a user-defined type <c>N(A_1, ..., A_k)</c>, - where each <c>A_i</c> is a type, then Rep(T) = - <c>{user_type,LINE,N,[Rep(A_1), ..., Rep(A_k)]}</c>.</item> + <item>If T is a user-defined type <c>N(T_1, ..., T_k)</c>, + then Rep(T) = + <c>{user_type,LINE,N,[Rep(T_1), ..., Rep(T_k)]}</c>.</item> <item>If T is <c>( T_0 )</c>, then Rep(T) = <c>Rep(T_0)</c>, that is, parenthesized types cannot be distinguished from their bodies.</item> @@ -563,15 +565,17 @@ <section> <title>Function Types</title> + <p>A function type Ft is one of the following alternatives:</p> <list type="bulleted"> <item>If Ft is a constrained function type <c>Ft_1 when Fc</c>, where <c>Ft_1</c> is a function type and <c>Fc</c> is a function constraint, then Rep(T) = - <c>{type,LINE,bounded_fun,[Rep(Ft_1),Rep(Fc)]}</c>.</item> - <item>If Ft is a function type <c>(A_1, ..., A_n) -> B</c>, - where each <c>A_i</c> and <c>B</c> are types, then - Rep(Ft) = <c>{type,LINE,'fun',[{type,LINE,product,[Rep(A_1), - ..., Rep(A_n)]},Rep(B)]}</c>.</item> + <c>{type,LINE,bounded_fun,[Rep(Ft_1),Rep(Fc)]}</c>. + For Rep(Fc), see below.</item> + <item>If Ft is a function type <c>(T_1, ..., T_n) -> T_0</c>, + where each <c>T_i</c> is a type, then + Rep(Ft) = <c>{type,LINE,'fun',[{type,LINE,product,[Rep(T_1), + ..., Rep(T_n)]},Rep(T_0)]}</c>.</item> </list> </section> @@ -587,6 +591,24 @@ </item> </list> </section> + + <section> + <title>Association Types</title> + <list type="bulleted"> + <item>If A is an association type <c>K => V</c>, where + <c>K</c> and <c>V</c> are types, then Rep(A) = + <c>{type,LINE,map_field_assoc,[Rep(K),Rep(V)]}</c>.</item> + </list> + </section> + + <section> + <title>Record Field Types</title> + <list type="bulleted"> + <item>If F is a record field type <c>Name :: Type</c>, + where <c>Type</c> is a type, then Rep(F) = + <c>{type,LINE,field_type,[Rep(Name),Rep(Type)]}</c>.</item> + </list> + </section> </section> <section> |