Previous: Default insts for functions, Up: Higher-order insts and modes [Contents]
A higher-order type may optionally specify an inst in the following manner:
(pred) is Determinism pred(Type::Mode) is Determinism pred(Type1::Mode1, Type2::Mode2) is Determinism … (func) = (Type::Mode) is Determinism func(Type1::Mode1) = (Type::Mode) is Determinism func(Type1::Mode1, Type2::Mode2) = (Type::Mode) is Determinism …
When used as argument types of functors in type declarations, types of this form have two effects. First, for any unification that constructs a term using such an argument, there is an additional mode constraint that the argument must be approximated by the inst. In other words, to be mode correct a program must not construct any term where a functor has an argument that does not have the declared inst, if present.
The second effect is that when a unification deconstructs a ground term to extract an argument with such a declared inst, the extracted argument may then be used as if it had that inst.
For example, given this type declaration:
:- type job ---> job(pred(int::out, io::di, io::uo) is det).
the following goal is correct:
:- pred run(job::in, io::di, io::uo) is det. run(Job, !IO) :- Job = job(Pred), Pred(Result, !IO), % Pred has the necessary inst write_line(Result, !IO).
However, the following would be a mode error:
:- pred bad(job::out) is det. bad(job(p)). % Error: p does not have required mode :- pred p(int::in, io::di, io::out) is det. …
As a new feature, combined higher-order types and insts are only permitted as direct arguments of functors in discriminated unions. So the following examples currently result in errors.
% Error: use on the RHS of equivalence types. :- type p == (pred(io::di, io::uo) is det). :- type f == (func(int::in) = (int::out) is semidet). % Error: use inside a type constructor. :- type jobs ---> jobs(list(pred(int::out, io::di, io::uo) is det)). % Error: use in a pred/func declaration. :- pred p((pred(io::di, io::uo) is det)::in, io::di, io::uo) is det. :- func f(func(int::in) = (int::out) is semidet, int) = int.
Future versions of the language may allow these forms.
Previous: Default insts for functions, Up: Higher-order insts and modes [Contents]