txt: ## typesystem.md
  ## Chunk 2 of 2
  ; $key => $value }));
  say ConfigValues.enums;          # OUTPUT: «Map.new((a => 1, b => 2))␤»
  
  ```
  
  Firstly, we read lines from `config` file, split every line using `words` method and return resulting pair for every line, thus creating a List of Pairs.
  
  ### [Typing Enums](#Type_system "go to top of document")[§](#Typing_Enums "direct link")
  
  When declaring enums with an explicit scope, a type may be provided, which will be used to typecheck the enum's values:
  
  ```raku
  my Str enum Foo (foo => 'foo');
  
  ```
  
  All enum pairs are typed as [`Enumeration`](/type/Enumeration). In addition, when the enum values are typed as [`Numeric`](/type/Numeric), [`Stringy`](/type/Stringy), or a combination of these two types, enum pairs also do the `NumericEnumeration`, `StringyEnumeration`, and `NumericStringyEnumeration` roles respectively. These simply determine how enum pairs get stringified with the [`Str`](/type/Str) method.
  
  Given that these types are roles, naturally you can provide your own roles when declaring an enum, which allows you to give them custom behavior and state. For example, to make it simpler to check if a number matches a flag in a bitmask enum, you could write a `BitmaskEnumeration` role with an `ACCEPTS` method to handle this via smartmatching:
  
  ```raku
  role BitmaskEnumeration {
      multi method ACCEPTS(::?CLASS:D: Int:D $value --> Bool:D) {
          so $value +& self.value
      }
  }
  
  enum Flags does BitmaskEnumeration (
      FLAG_FOO => 0b001,
      FLAG_BAR => 0b010,
      FLAG_BAZ => 0b100,
  );
  
  say 0b111 ~~ FLAG_FOO & FLAG_BAR & FLAG_BAZ; # OUTPUT: «True␤»
  
  ```
  
  ### [Metaclass](#Type_system "go to top of document")[§](#Metaclass_0 "direct link")
  
  To test if a given type object is an `enum`, test the metaobject method `.HOW` against [`Metamodel::EnumHOW`](/type/Metamodel/EnumHOW) or simply test against the [`Enumeration`](/type/Enumeration) role.
  
  ```raku
  enum E(<a b c>);
  say E.HOW ~~ Metamodel::EnumHOW; # OUTPUT: «True␤»
  say E ~~ Enumeration;            # OUTPUT: «True␤»
  ```
  
  ### [Methods](#Type_system "go to top of document")[§](#Methods_0 "direct link")
  
  See the [`Enumeration`](/type/Enumeration) role for available methods on enum types and enum-pairs.
  
  ### [Coercion](#Type_system "go to top of document")[§](#Coercion_0 "direct link")
  
  If you want to coerce the value of an enum element to its proper enum object, use the coercer with the name of the enum:
  
  ```raku
  my enum A (sun => 42, mon => 72);
  A(72).pair.say;   # OUTPUT: «mon => 72␤»
  A(1000).say; # OUTPUT: «(A)␤»
  ```
  
  The last example shows what happens if there is no enum-pair that includes that as a value.
  
  ## [`module`](#Type_system "go to top of document")[§](#module "direct link")
  
  Modules are usually one or more source files that expose Raku constructs, such as classes, roles, grammars, subroutines and variables. Modules are usually used for distributing Raku code as libraries which can be used in another Raku program.
  
  For a full explanation see [Modules](/language/modules).
  
  ## [`package`](#Type_system "go to top of document")[§](#package "direct link")
  
  Packages are nested namespaces of named program elements. Modules, classes and grammars are all types of package.
  
  For a full explanation see [Packages](/language/packages).
  
  ## [`grammar`](#Type_system "go to top of document")[§](#grammar "direct link")
  
  Grammars are a specific type of class intended for parsing text. Grammars are composed of rules, tokens and regexes which are actually methods, since grammars are classes.
  
  For a full explanation see [Grammars](/language/grammars).
  
  ## [`subset`](#Type_system "go to top of document")[§](#subset "direct link")
  
  A `subset` declares a new type that will re-dispatch to its base type. If a [`where`](/language/signatures#index-entry-where_clause) clause is supplied any assignment will be checked against the given code object.
  
  ```raku
  subset Positive of Int where * > -1;
  my Positive $i = 1;
  $i = -42;
  CATCH { default { put .^name,': ', .Str } }
  # OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $i; expected Positive but got Int (-42)␤»
  ```
  
  Subsets can be used in signatures, e.g. by typing the output:
  
  ```raku
  subset Foo of List where (Int,Str);
  sub a($a, $b, --> Foo) { $a, $b }
  # Only a List with the first element being an Int and the second a Str will pass the type check.
  a(1, "foo");  # passes
  a("foo", 1);  # fails
  ```
  
  If you skip the base type, it defaults to [`Any`](/type/Any). So the following two are equivalent:
  
  ```raku
  subset A-or-B where * ~~ A | B
  
  ```
  
  ```raku
  subset A-or-B of Any where * ~~ A | B
  
  ```
  
  Subsets can be anonymous, allowing inline placements where a subset is required but a name is neither needed nor desirable.
  
  ```raku
  my enum E1 <A B>;
  my enum E2 <C D>;
  sub g(@a where { .all ~~ subset :: where E1|E2 } ) {
      say @a
  }
  g([A, C]);
  # OUTPUT: «[A C]␤»
  ```
  
  Subsets can be used to check types dynamically, which can be useful in conjunction with [require](/language/modules#require).
  
  ```raku
  require ::('YourModule');
  subset C where ::('YourModule::C');
  
  ```
  
  # [Versioning, authorship, and API version.](#Type_system "go to top of document")[§](#Versioning,_authorship,_and_API_version. "direct link")
  
  When you declare a type you can pass it a version, author, and/or API number, all of which you can subsequently introspect. The versioning, authorship, and/or API number of a type can be applied via the adverbs `:ver<>`, `:auth<>`, and `:api<>` respectively. All of them take a string as argument; for `:ver` the string is converted to a [`Version`](/type/Version) object, and for `:api` the string is converted into an [allomorph](/language/glossary#Allomorph) [`IntStr`](/type/IntStr) object. `:auth` generally takes the form `hosting:ID`, as in `github:github-user` or `gitlab:gitlab-user`.
  
  To query the version, author, and API version of a type use [`.^ver`](/type/Metamodel/Versioning#method_ver), [`.^auth`](/type/Metamodel/Versioning#method_auth), and [`.^api`](/type/Metamodel/Versioning#method_api) respectively, as illustrated down below by querying a `class`.
  
  ```raku
  class C:ver<4.2.3>:auth<github:jane>:api<1> {}
  say C.^ver;       # OUTPUT: «v4.2.3␤»
  say C.^ver.parts; # OUTPUT: «(4 2 3)␤»
  say C.^auth;      # OUTPUT: «github:jane␤»
  say C.^api;       # OUTPUT: «1␤»
  ```
  
  In a similar fashion, `role`s, `grammar`s, and `module`s can be queried about the aforementioned information.
  