Did you know ... | Search Documentation: |
Pack logtalk -- logtalk-3.77.0/manuals/_sources/libraries/types.rst.txt |
.. _library_types:
types
This library implements predicates over standard Prolog term types and also terms representing common data structures such as lists and pairs.
It also includes a user-extensible type
object defining type
checking predicates over common Logtalk and Prolog term types. The types
define a hierarchy with the Prolog type term
at the root (i.e.
type-checking a predicate argument of type term
trivially succeeds).
Some types are only meaningful for backend Prolog systems supporting
non-universal features (e.g. cyclic
or char(CharSet)
with a
Unicode character set). See the API documentation for a full list of the
types defined by default.
Open the `../../docs/library_index.html#types <../../docs/library_index.html#types>`__ link in a web browser.
To load all entities in this library, load the loader.lgt
file:
::
| ?- logtalk_load(types(loader))
.
In case your code only requires the most basic types, you can load in alternative the file:
::
| ?- logtalk_load(basic_types(loader))
.
See the notes on the basic_types
virtual library for details.
To test this library predicates, load the tester.lgt
file:
::
| ?- logtalk_load(types(tester))
.
This library type
object can be used to type-check common Logtalk
and Prolog term types (see the object documentation for a listing of all
the pre-defined types). The valid/2 predicate succeeds or fails if a
term is of a given type. For example:
::
| ?- type::valid(positive_integer, 42)
.
yes
| ?- type::valid(positive_integer, -13)
.
no
The check/2 and check/3 predicates throw an exception if a term is not of a given type. For example:
::
| ?- catch(type::check(integer, abc), Error, true)
.
Error = type_error(integer, abc)
yes
If we require a standard error/2 exception term, the check/3 predicate takes a context argument. For example:
::
| ?- catch(type::check(integer, abc, foo/3), Error, true)
.
Error = error(type_error(integer, abc), foo/3)
yes
Typically, the context is provided by calling the built-in context/1 method.
To define a custom type, define clauses for the multifile predicates
type::type/1
(to declare the type) and type::check/2
(to
type-check values). For example:
::
:- multifile(type::type/1)
.
type::type(age)
.
:- multifile(type::check/2)
.
type::check(age, Term)
:-
type::check(between(non_negative_integer, 0, 150), Term)
.
Be careful to ensure that new type definitions don't introduce spurious
choice-points for these predicates. The unit tests of the types
library perform this check for pre-defined and loaded user-defined
ground types.
When defining a meta-type (i.e. a type with arguments that are also
types), add also a clause for the type::meta_type/3
multifile
predicate. For example:
::
:- multifile(type::meta_type/3)
.
type::meta_type(tuple(Type1, Type2, Type3), [Type1, Type2, Type3], [])
.
This predicate is called when checking if a type is a defined type. For meta-types, that check must extend to the sub-types.
See e.g. the os
library implementation of custom types for files and
directories. Or the expecteds
and optionals
libraries custom
types. See also the my_types
programming example.