- To define type spec for a functions
@spec function_name(arg_1_type, arg_2_type) :: return_type
- To define new type
@type new_type_name :: existing_type
- To document type place
@typedoc """ description """
above type definition.
- We can create product types such as lists, tuples and maps using their own syntax with members being the types.
- Eg. Product types
@type statuses :: [atom]
@type number_with_remark :: {number, String.t}
@type error_map :: %{
message: String.t,
line_number: integer
}
- We can create sum types like ok tuple and error tuple using
|
- Eg. Sum types
@type parse_response :: {:ok, term} | {:error, String.t}
- Custom types are exported along with the module. so we can use them in other modules using
Module_name.custom_type
- To make a custom type and its documentation private use
@typep
instead.
- Type specs also help in defining behaviour
- The functions that need to be implemented by the behavior are specified as
@callback function_name(arg_1_type, arg_2_type) :: return_type
- Eventhough
string
is a primitive type in Elixir, we should use String.t()
instead. string
represents erlang string which is implemented as char_list
.
String.t()
represents Elixir string implementation which can also be referred as binary,
- More info about basic types.
- More info about Literals
- Short hand to represent above types.
- If we want to create map with dynamic keys and values.
%{optional(any) => any}
- An opaque type, defined with
@opaque
is a type where the internal structure of the type will not be visible, but the type is still public.
- Types can be parameterized by defining variables as parameters; these variables can then be used to define the type.
@type dict(key, value) :: [{key, value}]
. When using dict(atom, integer | String.t())
.
- Guards can be used to restrict type variables given as arguments to the function.
@spec function(arg1, arg2) :: {arg1, arg2} when arg1: atom, arg2: integer
- Type variables with no restriction can also be defined using var.
@spec function(arg) :: [arg] when arg: var
- We can inline types as
@spec days_since_epoch(year :: integer, month :: integer, day :: integer) :: integer
@type color :: {red :: integer, green :: integer, blue :: integer}
@macrocallback
used to declare marcros inside behaviour.
@optional_callbacks non_vital_fun: 0, non_vital_macro: 1
related to behaviour, to define optional callback functions.
- To know about behaviour details
MyBehaviour.behaviour_info(:callbacks)
#=> [vital_fun: 0, "MACRO-non_vital_macro": 2, non_vital_fun: 0]
MyBehaviour.behaviour_info(:optional_callbacks)
#=> ["MACRO-non_vital_macro": 2, non_vital_fun: 0]
floor_div(integer(), neg_integer() | pos_integer()) :: integer()
Note that 0
is omitted by neg_interger | pos_integer
.