Typing system for places (and transitions guards). Types are contraint checkers to verify whether a value is in the type or not. For instance:

```>>> 5 in tInteger
True
>>> 4.3 in tInteger
False
```

The typechecking of several values is possible using the type as a function. It fails if one value is not in the type.

```>>> tInteger(5, 4, 6)
True
>>> tInteger(5, 4, 6.0)
False
```

Types can be composed in order to build more complexe types. For example:

```>>> 8 in (tInteger & ~Range(1, 5))
True
>>> 3 in (tInteger & ~Range(1, 5))
False
```

The various compositions are the same as sets operations, plus the complement: `&`, `|`, `-`, `^` and `~` (complement).

Various types are predefined (like `tInteger`) the others can be constructed using the various classes in the module. Prefefined types are:

• `tAll`: any value is in the type
• `tNothing`: empty type
• `tString`: string values
• `tList`: lists values
• `tInteger`: integer values
• `tNatural`: non-negative integers
• `tPositive`: strictly positive integers
• `tFloat`: float values
• `tNumber`: integers or float values
• `tDict`: Python's `dict` values
• `tNone`: the single value `None`
• `tBoolean`: `True` or `False`
• `tTuple`: tuple values
• `tPair`: tuples of length two

Types with finitely many elements can be iterated over:

```>>> list(sorted(iter(CrossProduct(Range(0, 10, 2), tBoolean) & ~OneOf((4, True), (6, False)))))
[(0, False), (0, True), (2, False), (2, True), (4, False), (6, True), (8, False), (8, True)]
>>> list(iter(OneOf(1, 2, 3)))
[1, 2, 3]
>>> iter(tInteger)
Traceback (most recent call last):
...
TypeError: ... not iterable
>>> iter(~OneOf(1, 2, 3))
Traceback (most recent call last):
...
TypeError: ... not iterable
```

### Class `Type`

```class Type (object) :
```

Base class for all types. Implements operations `&`, `|`, `-`, `^` and `~` to build new types. Also implement the typechecking of several values. All the subclasses should implement the method `__contains__` to typecheck a single object.

This class is abstract and should not be instantiated.

#### Method `Type.__and__`

```def __and__ (self, other) :
```

Intersection type.

```>>> Instance(int) & Greater(0)
(Instance(int) & Greater(0))
```
##### Call API
• `Type other`: the other type in the intersection
• `return Type`: the intersection of both types

#### Method `Type.__or__`

```def __or__ (self, other) :
```

Union type.

```>>> Instance(int) | Instance(bool)
(Instance(int) | Instance(bool))
```
##### Call API
• `Type other`: the other type in the union
• `return Type`: the union of both types

#### Method `Type.__sub__`

```def __sub__ (self, other) :
```

Substraction type.

```>>> Instance(int) - OneOf([0, 1, 2])
(Instance(int) - OneOf([0, 1, 2]))
```
##### Call API
• `Type other`: the other type in the substraction
• `return Type`: the type `self` minus the type `other`

#### Method `Type.__xor__`

```def __xor__ (self, other) :
```

Disjoint union type.

```>>> Greater(0) ^ Instance(float)
(Greater(0) ^ Instance(float))
```
##### Call API
• `Type other`: the other type in the disjoint union
• `return Type`: the disjoint union of both types

#### Method `Type.__invert__`

```def __invert__ (self) :
```

Complementary type.

```>>> ~ Instance(int)
(~Instance(int))
```
##### Call API
• `return Type`: the complementary type

#### Method `Type.__call__`

```def __call__ (self, *values) :
```

Typecheck values.

```>>> Instance(int)(3, 4, 5)
True
>>> Instance(int)(3, 4, 5.0)
False
```
##### Call API
• `object values`: values that have to be checked
• `return bool`: `True` if all the values are in the types, `False` otherwise

### Class `Instance`

```class Instance (Type) :
```

A type whose values are all instances of one class.

```>>> [1, 2] in Instance(list)
True
>>> (1, 2) in Instance(list)
False
```

#### Method `Instance.__init__`

```def __init__ (self, _class) :
```

Initialize the type

```>>> Instance(int)
Instance(int)
```
##### Call API
• `class _class`: the class of instance
• `return Instance`: initialized object

### Class `TypeCheck`

```class TypeCheck (Type) :
```

A type whose values are accepted by a given function.

```>>> def odd (val) :
...     return type(val) is int and (val % 2) == 1
>>> 3 in TypeCheck(odd)
True
>>> 4 in TypeCheck(odd)
False
>>> 3.0 in TypeCheck(odd)
False
```

#### Method `TypeCheck.__init__`

```def __init__ (self, checker, iterate=None) :
```

Initialize the type, optionally, a function to iterate over the elements may be provided.

```>>> import operator
>>> TypeCheck(operator.truth)
TypeCheck(...truth)
>>> list(TypeCheck(operator.truth))
Traceback (most recent call last):
...
ValueError: type not iterable
>>> def true_values () : # enumerates only choosen values
...     yield True
...     yield 42
...     yield '42'
...     yield [42]
...     yield (42,)
...     yield {True: 42}
>>> TypeCheck(operator.truth, true_values)
TypeCheck(...truth, snakes.typing.true_values)
>>> list(TypeCheck(operator.truth, true_values))
[True, 42, '42', [42], (42,), {True: 42}]
```
##### Call API
• `callable checker`: a function that checks one value and returns `True` if it is in te type and `False` otherwise
• `generator iterate`: `None` or an iterator over the values of the type

### Class `OneOf`

```class OneOf (Type) :
```

A type whose values are explicitely enumerated.

```>>> 3 in OneOf(1, 2, 3, 4, 5)
True
>>> 0 in OneOf(1, 2, 3, 4, 5)
False
```

### Class `Collection`

```class Collection (Type) :
```

A type whose values are a given container, holding items of a given type and ranging in a given interval.

```>>> [0, 1.1, 2, 3.3, 4] in Collection(Instance(list), tNumber, 3, 10)
True
>>> [0, 1.1] in Collection(Instance(list), tNumber, 3, 10) #too short
False
>>> [0, '1.1', 2, 3.3, 4] in Collection(Instance(list), tNumber, 3, 10) #wrong item
False
```

#### Method `Collection.__init__`

```def __init__ (self, collection, items, min=None, max=None) :
```

Initialise the type

```>>> Collection(Instance(list), tNumber, 3, 10)
Collection(Instance(list), (Instance(int) | Instance(float)), min=3, max=10)
```
##### Call API
• `Type collection`: the collection type
• `Type items`: the type of the items
• `object min`: the smallest allowed value
• `object max`: the greatest allowed value

### Function `List`

```def List (items, min=None, max=None) :
```

Shorthand for instantiating `Collection`

```>>> List(tNumber, min=3, max=10)
Collection(Instance(list), (Instance(int) | Instance(float)), min=3, max=10)
```
##### Call API
• `Type items`: the type of the elements in the collection
• `int min`: the minimum number of elements in the collection or `None`
• `int max`: the maximum number of elements in the collection or `None`
• `return Collection`: a type that checks the given constraints

### Function `Tuple`

```def Tuple (items, min=None, max=None) :
```

Shorthand for instantiating `Collection`

```>>> Tuple(tNumber, min=3, max=10)
Collection(Instance(tuple), (Instance(int) | Instance(float)), min=3, max=10)
```
##### Call API
• `Type items`: the type of the elements in the collection
• `int min`: the minimum number of elements in the collection or `None`
• `int max`: the maximum number of elements in the collection or `None`
• `return Collection`: a type that checks the given constraints

### Function `Set`

```def Set (items, min=None, max=None) :
```

Shorthand for instantiating `Collection`

```>>> Set(tNumber, min=3, max=10)
Collection(Instance(set), (Instance(int) | Instance(float)), min=3, max=10)
```
##### Call API
• `Type items`: the type of the elements in the collection
• `int min`: the minimum number of elements in the collection or `None`
• `int max`: the maximum number of elements in the collection or `None`
• `return Collection`: a type that checks the given constraints

### Class `Mapping`

```class Mapping (Type) :
```

A type whose values are mapping (eg, `dict`)

```>>> {'Yes': True, 'No': False} in Mapping(tString, tAll)
True
>>> {True: 1, False: 0} in Mapping(tString, tAll)
False
```

#### Method `Mapping.__init__`

```def __init__ (self, keys, items, _dict=Instance(dict)) :
```

Initialise a mapping type

```>>> Mapping(tInteger, tFloat)
Mapping(Instance(int), Instance(float), Instance(dict))
>>> from snakes.data import hdict
>>> Mapping(tInteger, tFloat, Instance(hdict))
Mapping(Instance(int), Instance(float), Instance(hdict))
```
##### Call API
• `Type keys`: the type for the keys
• `Type items`: the type for the items
• `dict _dict`: the class that mapping must be instances of

### Class `Range`

```class Range (Type) :
```

A type whose values are in a given range

Notice that ranges are not built into the memory so that huge values can be used.

```>>> 3 in Range(1, 2**128, 2)
True
>>> 4 in Range(1, 2**128, 2)
False
```

#### Method `Range.__init__`

```def __init__ (self, first, last, step=1) :
```

The values are those that the builtin ```range(first, last, step)``` would return.

```>>> Range(1, 10)
Range(1, 10)
>>> Range(1, 10, 2)
Range(1, 10, 2)
```
##### Call API
• `int first`: first element in the range
• `int last`: upper bound of the range, not belonging to it
• `int step`: step between elements in the range

### Class `Greater`

```class Greater (Type) :
```

A type whose values are greater than a minimum.

The minimum and the checked values can be of any type as soon as they can be compared with `>`.

```>>> 6 in Greater(3)
True
>>> 3 in Greater(3)
False
```

#### Method `Greater.__init__`

```def __init__ (self, min) :
```

Initialises the type

```>>> Greater(5)
Greater(5)
```
##### Call API
• `object min`: the greatest value not included in the type

### Class `GreaterOrEqual`

```class GreaterOrEqual (Type) :
```

A type whose values are greater or equal than a minimum.

See the description of `Greater`

#### Method `GreaterOrEqual.__init__`

```def __init__ (self, min) :
```

Initialises the type

```>>> GreaterOrEqual(5)
GreaterOrEqual(5)
```
##### Call API
• `object min`: the minimal allowed value

### Class `Less`

```class Less (Type) :
```

A type whose values are less than a maximum.

See the description of `Greater`

#### Method `Less.__init__`

```def __init__ (self, max) :
```

Initialises the type

```>>> Less(5)
Less(5)
```
##### Call API
• `object max`

### Class `LessOrEqual`

```class LessOrEqual (Type) :
```

A type whose values are less than or equal to a maximum.

See the description of `Greater`

#### Method `LessOrEqual.__init__`

```def __init__ (self, max) :
```

Initialises the type

```>>> LessOrEqual(5)
LessOrEqual(5)
```
##### Call API
• `object max`

### Class `CrossProduct`

```class CrossProduct (Type) :
```

A type whose values are tuples, each component of them being in given types. The resulting type is the cartesian cross product of the compound types.

```>>> (1, 3, 5) in CrossProduct(Range(1, 10), Range(1, 10, 2), Range(1, 10))
True
>>> (2, 4, 6) in CrossProduct(Range(1, 10), Range(1, 10, 2), Range(1, 10))
False
```

#### Method `CrossProduct.__init__`

```def __init__ (self, *types) :
```

Initialise the type

```>>> CrossProduct(Instance(int), Instance(float))
CrossProduct(Instance(int), Instance(float))
```
##### Call API
• `Type types`: the types of each component of the allowed tuples