# Module proper_types

- Description
- Data Types
- Function Index
- Function Details

Type manipulation functions and predefined types.

Copyright © 2010-2022 Manolis Papadakis, Eirini Arvaniti, and Kostis Sagonas

Authors: Manolis Papadakis.

## Description

Type manipulation functions and predefined types.

### Basic types

This module defines all the basic types of the PropEr type system as functions. See the function index for an overview.

Types can be combined in tuples or lists to produce other types. Exact values (such as exact numbers, atoms, binaries and strings) can be combined with types inside such structures, like in this example of the type of a tagged tuple: `{'result', integer()}`.

When including the PropEr header file, all API functions of this module are automatically imported, unless `PROPER_NO_IMPORTS` is defined.

### Customized types

The following operators can be applied to basic types in order to produce new ones:

`?LET(<Xs>, <Xs_type>, <In>)`
  To produce an instance of this type, all appearances of the variables in `<Xs>` are replaced inside `<In>` by their corresponding values in a randomly generated instance of `<Xs_type>`. It's OK for the `<In>` part to evaluate to a type - in that case, an instance of the inner type is generated recursively.
`?SUCHTHAT(<X>, <Type>, <Condition>)`
  This produces a specialization of `<Type>`, which only includes those members of `<Type>` that satisfy the constraint `<Condition>` - that is, those members for which the function `fun(<X>) -> <Condition> end` returns `true`. If the constraint is very strict - that is, only a small percentage of instances of `<Type>` pass the test - it will take a lot of tries for the instance generation subsystem to randomly produce a valid instance. This will result in slower testing, and testing may even be stopped short, in case the `constraint_tries` limit is reached (see the "Options" section in the documentation of the `proper` module). If this is the case, it would be more appropriate to generate valid instances of the specialized type using the `?LET` macro. Also make sure that even small instances can satisfy the constraint, since PropEr will only try small instances at the start of testing. If this is not possible, you can instruct PropEr to start at a larger size, by supplying a suitable value for the `start_size` option (see the "Options" section in the documentation of the `proper` module).
`?SUCHTHATMAYBE(<X>, <Type>, <Condition>)`
  Equivalent to the `?SUCHTHAT` macro, but the constraint `<Condition>` is considered non-strict: if the `constraint_tries` limit is reached, the generator will just return an instance of `<Type>` instead of failing, even if that instance doesn't satisfy the constraint.
`?SHRINK(<Generator>, <List_of_alt_gens>)`
  This creates a type whose instances are generated by evaluating the statement block `<Generator>` (this may evaluate to a type, which will then be generated recursively). If an instance of such a type is to be shrunk, the generators in `<List_of_alt_gens>` are first run to produce hopefully simpler instances of the type. Thus, the generators in the second argument should be simpler than the default. The simplest ones should be at the front of the list, since those are the generators preferred by the shrinking subsystem. Like the main `<Generator>`, the alternatives may also evaluate to a type, which is generated recursively.
`?LETSHRINK(<List_of_variables>, <List_of_types>, <Generator>)`
  This is created by combining a `?LET` and a `?SHRINK` macro. Instances are generated by applying a randomly generated list of values inside `<Generator>` (just like a `?LET`, with the added constraint that the variables and types must be provided in a list - alternatively, `<List_of_types>` may be a list or vector type). When shrinking instances of such a type, the sub-instances that were combined to produce it are first tried in place of the failing instance.
`?LAZY(<Generator>)`
  This construct returns a type whose only purpose is to delay the evaluation of `<Generator>` (`<Generator>` can return a type, which will be generated recursively). Using this, you can simulate the lazy generation of instances:

               stream() -> ?LAZY(frequency([ {1,[]}, {3,[0|stream()]} ])).

  The above type produces lists of zeroes with an average length of 3. Note that, had we not enclosed the generator with a `?LAZY` macro, the evaluation would continue indefinitely, due to the eager evaluation of the Erlang language.
`non_empty(<List_or_binary_type>)`
  See the documentation for `non_empty/1`.
`noshrink(<Type>)`
  See the documentation for `noshrink/1`.
`default(<Default_value>, <Type>)`
  See the documentation for `default/2`.
`with_parameter(<Parameter>, <Value>, <Type>)`
  See the documentation for `with_parameter/3`.
`with_parameters(<Param_value_pairs>, <Type>)`
  See the documentation for `with_parameters/2`.

### Size manipulation

The following operators are related to the `size` parameter, which controls the maximum size of produced instances. The actual size of a produced instance is chosen randomly, but can never exceed the value of the `size` parameter at the moment of generation. A more accurate definition is the following: the maximum instance of `size S` can never be smaller than the maximum instance of `size S-1`. The actual size of an instance is measured differently for each type: the actual size of a list is its length, while the actual size of a tree may be the number of its internal nodes. Some types, e.g. unions, have no notion of size, thus their generation is not influenced by the value of `size`. The `size` parameter starts at 1 and grows automatically during testing.

`?SIZED(<S>, <Generator>)`
  Creates a new type, whose instances are produced by replacing all appearances of the `<S>` parameter inside the statement block `<Generator>` with the value of the `size` parameter. It's OK for the `<Generator>` to return a type - in that case, an instance of the inner type is generated recursively.
`resize(<New_size>, <Type>)`
  See the documentation for `resize/2`.

## Data Types

### extint()

    extint() = integer() | inf

### extnum()

    extnum() = number() | inf

### frequency()

    frequency() = non_neg_integer()

### length()

    length() = non_neg_integer()

### loose_tuple()

    loose_tuple(T) =
        {} |
        {T} |
        {T, T} |
        {T, T, T} |
        {T, T, T, T} |
        {T, T, T, T, T} |
        {T, T, T, T, T, T} |
        {T, T, T, T, T, T, T} |
        {T, T, T, T, T, T, T, T} |
        {T, T, T, T, T, T, T, T, T} |
        {T, T, T, T, T, T, T, T, T, T} |
        tuple()

Internal types

### raw_type()

    raw_type() =
        type() | [raw_type()] | loose_tuple(raw_type()) | term()

You can consider this as an equivalent of `type()`.

### type()

abstract datatype: `type()`

A type of the PropEr type system

### type_prop_name()

    type_prop_name() =
        kind | generator | reverse_gen | parts_type | combine |
        alt_gens | shrink_to_parts | size_transform | is_instance |
        shrinkers | noshrink | internal_type | internal_types |
        get_length | split | join | get_indices | remove | retrieve |
        update | constraints | parameters | env | subenv | user_nf |
        is_user_nf | matcher

### type_prop_value()

    type_prop_value() = term()

### value()

    value() = term()

## Function Index

add_prop/3 |
any/0 | All Erlang terms (that PropEr can produce).
arity/0 | Equivalent to `integer(0, 255)`.
atom/0 | All atoms.
binary/0 | All binaries.
binary/1 | All binaries with a byte size of `Len`.
bitstring/0 | All bitstrings.
bitstring/1 | All bitstrings with a bit size of `Len`.
bool/0 | Equivalent to `boolean()`.
boolean/0 | The atoms `true` and `false`.
byte/0 | Equivalent to `integer(0, 255)`.
char/0 | Equivalent to `integer(0, 1114111)`.
choose/2 | Equivalent to `integer(Low, High)`.
default/2 | Adds a default value, `Default`, to `Type`.
elements/1 | Equivalent to `union(Choices)`.
exactly/1 | Singleton type consisting only of `E`.
fixed_list/1 | All lists whose i-th element is an instance of the type at index i of `ListOfTypes`.
float/0 | Equivalent to `float(inf, inf)`.
float/2 | All floats between `Low` and `High`, bounds included.
frequency/1 | Equivalent to `weighted_union(Choices)`.
function/2 | All pure functions that map instances of `ArgTypes` to instances of `RetType`.
function0/1 | Equivalent to `function(0, RetType)`.
function1/1 | Equivalent to `function(1, RetType)`.
function2/1 | Equivalent to `function(2, RetType)`.
function3/1 | Equivalent to `function(3, RetType)`.
function4/1 | Equivalent to `function(4, RetType)`.
int/0 | Small integers (bound by the current value of the `size` parameter).
integer/0 | Equivalent to `integer(inf, inf)`.
integer/2 | All integers between `Low` and `High`, bounds included.
largeint/0 | Equivalent to `integer()`.
list/0 | Equivalent to `list(any())`.
list/1 | All lists containing elements of type `ElemType`.
loose_tuple/1 | Tuples whose elements are all of type `ElemType`.
map/0 | Equivalent to `map(any(), any())`.
map/2 | A map whose keys are defined by the generator `K` and values by the generator `V`.
nat/0 | Small non-negative integers (bound by the current value of the `size` parameter).
neg_integer/0 | Equivalent to `integer(inf, -1)`.
nil/0 | Equivalent to `exactly([])`.
non_empty/1 | This is a predefined constraint that can be applied to random-length list and binary types to ensure that the produced values are never empty.
non_neg_float/0 | Equivalent to `float(0.0, inf)`.
non_neg_integer/0 | Equivalent to `integer(0, inf)`.
noshrink/1 | Creates a new type which is equivalent to `Type`, but whose instances are never shrunk by the shrinking subsystem.
number/0 | Equivalent to `union([integer(), float()])`.
oneof/1 | Equivalent to `union(Choices)`.
orderedlist/1 | All sorted lists containing elements of type `ElemType`.
parameter/1 | Equivalent to `parameter(Parameter, undefined)`.
parameter/2 | Returns the value associated with `Parameter`, or `Default` in case `Parameter` is not associated with any value.
pos_integer/0 | Equivalent to `integer(1, inf)`.
range/2 | Equivalent to `integer(Low, High)`.
real/0 | Equivalent to `float()`.
resize/2 | Overrides the `size` parameter used when generating instances of `Type` with `NewSize`.
return/1 | Equivalent to `exactly(E)`.
shrink_list/1 | A type that generates exactly the list `List`.
string/0 | Equivalent to `list(char())`.
term/0 | Equivalent to `any()`.
timeout/0 | Equivalent to `union([non_neg_integer() | infinity])`.
tuple/0 | Equivalent to `loose_tuple(any())`.
tuple/1 | All tuples whose i-th element is an instance of the type at index i of `ListOfTypes`.
union/1 | The union of all types in `ListOfTypes`.
vector/2 | All lists of length `Len` containing elements of type `ElemType`.
weighted_default/2 | A specialization of `default/2`, where `Default` and `Type` are assigned weights to be considered by the random instance generator.
weighted_union/1 | A specialization of `union/1`, where each type in `ListOfTypes` is assigned a frequency.
with_parameter/3 | Associates the atom key `Parameter` with the value `Value` while generating instances of `Type`.
with_parameters/2 | Similar to `with_parameter/3`, but accepts a list of `{Parameter, Value}` pairs.
wunion/1 | Equivalent to `weighted_union(FreqChoices)`.

## Function Details

### add_prop/3

    add_prop(PropName :: type_prop_name(),
             Value :: type_prop_value(),
             X3 :: proper_types:type()) ->
                proper_types:type()

### any/0

    any() -> proper_types:type()

All Erlang terms (that PropEr can produce). For reasons of efficiency, functions are never produced as instances of this type.
CAUTION: Instances of this type are expensive to produce, shrink and instance- check, both in terms of processing time and consumed memory. Only use this type if you are certain that you need it.

### arity/0

    arity() -> proper_types:type()

Equivalent to `integer(0, 255)`.

### atom/0

    atom() -> proper_types:type()

All atoms. All atoms used internally by PropEr start with a '`$`', so such atoms will never be produced as instances of this type. You should also refrain from using such atoms in your code, to avoid a potential clash. Instances shrink towards the empty atom, ''.

### binary/0

    binary() -> proper_types:type()

All binaries. Instances shrink towards the empty binary, `<<>>`.

### binary/1

    binary(Len :: length()) -> proper_types:type()

All binaries with a byte size of `Len`. `Len` must be an Erlang expression that evaluates to a non-negative integer. Instances shrink towards binaries of zeroes.

### bitstring/0

    bitstring() -> proper_types:type()

All bitstrings. Instances shrink towards the empty bitstring, `<<>>`.

### bitstring/1

    bitstring(Len :: length()) -> proper_types:type()

All bitstrings with a bit size of `Len`. `Len` must be an Erlang expression that evaluates to a non-negative integer. Instances shrink towards bitstrings of zeroes

### bool/0

    bool() -> proper_types:type()

Equivalent to `boolean()`.

### boolean/0

    boolean() -> proper_types:type()

The atoms `true` and `false`. Instances shrink towards `false`.

### byte/0

    byte() -> proper_types:type()

Equivalent to `integer(0, 255)`.

### char/0

    char() -> proper_types:type()

Equivalent to `integer(0, 1114111)`.

### choose/2

    choose(Low :: extint(), High :: extint()) -> proper_types:type()

Equivalent to `integer(Low, High)`.

### default/2

    default(Default :: raw_type(), Type :: raw_type()) ->
               proper_types:type()

Adds a default value, `Default`, to `Type`. The default serves as a primary shrinking target for instances, while it is also chosen by the random instance generation subsystem half the time.

### elements/1

    elements(Choices :: [raw_type(), ...]) -> proper_types:type()

Equivalent to `union(Choices)`.

### exactly/1

    exactly(E :: term()) -> proper_types:type()

Singleton type consisting only of `E`. `E` must be an evaluated term. Also written simply as `E`.

### fixed_list/1

    fixed_list(ListOfTypes ::
                   maybe_improper_list(raw_type(), raw_type() | [])) ->
                  proper_types:type()

All lists whose i-th element is an instance of the type at index i of `ListOfTypes`. Also written simply as a list of types.

### float/0

    float() -> proper_types:type()

Equivalent to `float(inf, inf)`.

### float/2

    float(Low :: extnum(), High :: extnum()) -> proper_types:type()

All floats between `Low` and `High`, bounds included. `Low` and `High` must be Erlang expressions that evaluate to floats, with `Low =< High`. Additionally, `Low` and `High` may have the value `inf`, in which case they represent minus infinity and plus infinity respectively. Instances shrink towards 0.0 if `Low =< 0.0 =< High`, or towards the bound with the smallest absolute value otherwise.

### frequency/1

    frequency(FreqChoices :: [{frequency(), raw_type()}, ...]) ->
                 proper_types:type()

Equivalent to `weighted_union(Choices)`.

### function/2

    function(ArgTypes :: [raw_type()] | arity(),
             RetType :: raw_type()) ->
                proper_types:type()

All pure functions that map instances of `ArgTypes` to instances of `RetType`. The syntax `function(Arity, RetType)` is also acceptable.

### function0/1

    function0(RetType :: raw_type()) -> proper_types:type()

Equivalent to `function(0, RetType)`.

### function1/1

    function1(RetType :: raw_type()) -> proper_types:type()

Equivalent to `function(1, RetType)`.

### function2/1

    function2(RetType :: raw_type()) -> proper_types:type()

Equivalent to `function(2, RetType)`.

### function3/1

    function3(RetType :: raw_type()) -> proper_types:type()

Equivalent to `function(3, RetType)`.

### function4/1

    function4(RetType :: raw_type()) -> proper_types:type()

Equivalent to `function(4, RetType)`.

### int/0

    int() -> proper_types:type()

Small integers (bound by the current value of the `size` parameter). Instances shrink towards `0`.

### integer/0

    integer() -> proper_types:type()

Equivalent to `integer(inf, inf)`.

### integer/2

    integer(Low :: extint(), High :: extint()) -> proper_types:type()

All integers between `Low` and `High`, bounds included. `Low` and `High` must be Erlang expressions that evaluate to integers, with `Low =< High`. Additionally, `Low` and `High` may have the value `inf`, in which case they represent minus infinity and plus infinity respectively. Instances shrink towards 0 if `Low =< 0 =< High`, or towards the bound with the smallest absolute value otherwise.

### largeint/0

    largeint() -> proper_types:type()

Equivalent to `integer()`.

### list/0

    list() -> proper_types:type()

Equivalent to `list(any())`.

### list/1

    list(ElemType :: raw_type()) -> proper_types:type()

All lists containing elements of type `ElemType`. Instances shrink towards the empty list, `[]`.

### loose_tuple/1

    loose_tuple(ElemType :: raw_type()) -> proper_types:type()

Tuples whose elements are all of type `ElemType`. Instances shrink towards the 0-size tuple, `{}`.

### map/0

    map() -> proper_types:type()

Equivalent to `map(any(), any())`.

### map/2

    map(K :: raw_type(), V :: raw_type()) -> proper_types:type()

A map whose keys are defined by the generator `K` and values by the generator `V`.

### nat/0

    nat() -> proper_types:type()

Small non-negative integers (bound by the current value of the `size` parameter). Instances shrink towards `0`.

### neg_integer/0

    neg_integer() -> proper_types:type()

Equivalent to `integer(inf, -1)`.

### nil/0

    nil() -> proper_types:type()

Equivalent to `exactly([])`.

### non_empty/1

    non_empty(ListType :: raw_type()) -> proper_types:type()

This is a predefined constraint that can be applied to random-length list and binary types to ensure that the produced values are never empty.

e.g. `list/0`, `string/0`, `binary/0`)

### non_neg_float/0

    non_neg_float() -> proper_types:type()

Equivalent to `float(0.0, inf)`.

### non_neg_integer/0

    non_neg_integer() -> proper_types:type()

Equivalent to `integer(0, inf)`.

### noshrink/1

    noshrink(Type :: raw_type()) -> proper_types:type()

Creates a new type which is equivalent to `Type`, but whose instances are never shrunk by the shrinking subsystem.

### number/0

    number() -> proper_types:type()

Equivalent to `union([integer(), float()])`.

### oneof/1

    oneof(Choices :: [raw_type(), ...]) -> proper_types:type()

Equivalent to `union(Choices)`.

### orderedlist/1

    orderedlist(ElemType :: raw_type()) -> proper_types:type()

All sorted lists containing elements of type `ElemType`. Instances shrink towards the empty list, `[]`.

### parameter/1

    parameter(Parameter :: atom()) -> value()

Equivalent to `parameter(Parameter, undefined)`.

### parameter/2

    parameter(Parameter :: atom(), Default :: value()) -> value()

Returns the value associated with `Parameter`, or `Default` in case `Parameter` is not associated with any value.

### pos_integer/0

    pos_integer() -> proper_types:type()

Equivalent to `integer(1, inf)`.

### range/2

    range(Low :: extint(), High :: extint()) -> proper_types:type()

Equivalent to `integer(Low, High)`.

### real/0

    real() -> proper_types:type()

Equivalent to `float()`.

### resize/2

    resize(NewSize :: proper_gen:size(), Type :: raw_type()) ->
              proper_types:type()

Overrides the `size` parameter used when generating instances of `Type` with `NewSize`. Has no effect on size-less types, such as unions. Also, this will not affect the generation of any internal types contained in `Type`, such as the elements of a list - those will still be generated using the test-wide value of `size`. One use of this function is to modify types to produce instances that grow faster or slower, like so:

         ?SIZED(Size, resize(Size * 2, list(integer()))

The above specifies a list type that grows twice as fast as normal lists.

### return/1

    return(E :: term()) -> proper_types:type()

Equivalent to `exactly(E)`.

### shrink_list/1

    shrink_list(List :: list()) -> proper_types:type()

A type that generates exactly the list `List`. Instances shrink towards shorter sublists of the original list.

### string/0

    string() -> proper_types:type()

Equivalent to `list(char())`.

### term/0

    term() -> proper_types:type()

Equivalent to `any()`.

### timeout/0

    timeout() -> proper_types:type()

Equivalent to `union([non_neg_integer() | infinity])`.

### tuple/0

    tuple() -> proper_types:type()

Equivalent to `loose_tuple(any())`.

### tuple/1

    tuple(ListOfTypes :: [raw_type()]) -> proper_types:type()

All tuples whose i-th element is an instance of the type at index i of `ListOfTypes`. Also written simply as a tuple of types.

### union/1

    union(ListOfTypes :: [raw_type(), ...]) -> proper_types:type()

The union of all types in `ListOfTypes`. `ListOfTypes` can't be empty. The random instance generator is equally likely to choose any one of the types in `ListOfTypes`. The shrinking subsystem will always try to shrink an instance of a type union to an instance of the first type in `ListOfTypes`, thus you should write the simplest case first.

### vector/2

    vector(Len :: length(), ElemType :: raw_type()) ->
              proper_types:type()

All lists of length `Len` containing elements of type `ElemType`. `Len` must be an Erlang expression that evaluates to a non-negative integer.

### weighted_default/2

    weighted_default(Default :: {frequency(), raw_type()},
                     Type :: {frequency(), raw_type()}) ->
                        proper_types:type()

A specialization of `default/2`, where `Default` and `Type` are assigned weights to be considered by the random instance generator. The shrinking subsystem will ignore the weights and try to shrink using the default value.

### weighted_union/1

    weighted_union(ListOfTypes :: [{frequency(), raw_type()}, ...]) ->
                      proper_types:type()

A specialization of `union/1`, where each type in `ListOfTypes` is assigned a frequency. Frequencies must be Erlang expressions that evaluate to non-negative integers. Types with larger frequencies are more likely to be chosen by the random instance generator. The shrinking subsystem will ignore the frequencies and try to shrink towards the first type in the list with a non-zero frequency.

### with_parameter/3

    with_parameter(Parameter :: atom(),
                   Value :: value(),
                   Type :: raw_type()) ->
                      proper_types:type()

Associates the atom key `Parameter` with the value `Value` while generating instances of `Type`.

### with_parameters/2

    with_parameters(PVlist :: [{atom(), value()}], Type :: raw_type()) ->
                       proper_types:type()

Similar to `with_parameter/3`, but accepts a list of `{Parameter, Value}` pairs.

### wunion/1

    wunion(FreqChoices :: [{frequency(), raw_type()}, ...]) ->
              proper_types:type()

Equivalent to `weighted_union(FreqChoices)`.

Generated by EDoc