-
Notifications
You must be signed in to change notification settings - Fork 37
Map types
Map types can have optional associations K => V and mandatory associations K := V.
If a map type doesn't mention a key of a certain type, such keys are forbidden in maps of that type. For example, #{} is the empty map type, so if a map value has any key at all, it is not a value of type #{}.
Map types have the same syntax as map expressions, but with a different meaning of => and :=, which may be confusing. We'll try to always use the words map type when we refer to a map type.
Subtyping for map types needs some documentation. Here is a draft.
A for subtyping in general, T1 is a subtype of T2 if all values/expressions/patterns of type T1 are also values/expressions/patterns of type T2. We use T1 :: T2 to denote subtyping. (It is actually compatible subtyping.)
- Type
#{}: The empty map type has only one value: The empty map#{}. No keys are allowed. - Type
#{a := b}: A map with a mandatory key of typeawhich maps to a value of typeb. There is only one such map:#{a => b}. - Type
#{a => b}: A map with an optional keya, so it has two values:#{a => b}and#{}.
We can see that #{} :: #{a => b} and #{a := b} :: #{a => b}.
Given two map types M1, M2.
M1 :: M2 if and only if the following two conditions are fulfilled:
-
For all associations
K1 <Assoc1> V1inM1, there exists an associationK2 <Assoc2> V2inM2such that-
K1 :: K2, -
V1 :: V2, -
<Assoc1>is mandatory if<Assoc2>is mandatory, - the association
K2 <Assoc2> V2is the first association inM2with a matching a keyK2such thatK1 :: K2.
The third bullet means that {Assoc1, Assoc2} must be one of the following three combinations:
{=>, =>},{:=, =>}or{:=, :=}.The forth bullet accounts for the quote "The key types in
AssociationListare allowed to overlap, and if they do, the leftmost association takes precedence" from Erlang Types and Function Specifications. -
-
For all mandatory associations
K2 := V2inM2, there is a mandatory associationK1 := V1inM1such thatK1 :: K2V1 :: V2
A mandatory key is typically a singleton such as a specific atom or integer, but what if a mandatory association is used for a non-singleton type as the key? We interpret it as that at least one key of the type is required.
Example: The type #{a | b :: c} is a map type where a key of type a | b is mandatory, i.e. a or b. Thus, the values of this type are #{a :: c}, #{b :: c} and #{a :: c, b :: c}.