[m-users.] Existential higher-order type
Peter Wang
novalazy at gmail.com
Tue Oct 11 17:06:24 AEDT 2022
On Tue, 11 Oct 2022 07:28:59 +0200 Volker Wysk <post at volker-wysk.de> wrote:
> > > You can use dynamic_cast for this sort of thing, but I can't say where
> > > without knowing how you've declared the checker.
> >
> > Hmm... Here's the declaration of dynamic_cast:
> >
> > % dynamic_cast(X, Y) succeeds with Y = X iff X has the same ground type
> > % as Y (so this may succeed if Y is of type list(int), say, but not if
> > % Y is of type list(T)).
> > %
> > :- pred dynamic_cast(T1::in, T2::out) is semidet.
> >
> > What's a "ground type"? What does it do, except for a unification?
It means a type without type variables.
>
> I've looked at the definition of dynamic_cast. It's a synonym for
> private_builtin.typed_unify/2. So it won't work for me.
Does the attached example help?
Peter
-------------- next part --------------
%-----------------------------------------------------------------------------%
:- module t.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module list.
:- type checker
---> some [T] checker(checker_pred(T)) => argument(T).
:- type checker_pred(T)
---> checker_pred(pred(T::in) is det).
:- typeclass argument(T) where [].
:- instance argument(int) where [].
:- pred int_checker(int::in) is det.
int_checker(Arg) :-
trace [io(!IO)] (
print_line({"int_checker", Arg}, !IO)
).
:- instance argument(string) where [].
:- pred string_checker(string::in) is det.
string_checker(Arg) :-
trace [io(!IO)] (
print_line({"string_checker", Arg}, !IO)
).
:- pred test_checker(list(checker)::in, int::in, T::in, io::di, io::uo) is det
<= argument(T).
test_checker(List, Index, Arg, !IO) :-
list.det_index0(List, Index, Elem),
Elem = checker(CheckerPred0),
( if dynamic_cast(CheckerPred0, CheckerPred) then
CheckerPred = checker_pred(Pred),
Pred(Arg)
else
print_line("dynamic_cast failed", !IO)
).
main(!IO) :-
List = [
'new checker'(checker_pred(int_checker)),
'new checker'(checker_pred(string_checker))
],
test_checker(List, 0, 123, !IO),
test_checker(List, 1, "abc", !IO),
test_checker(List, 1, 123, !IO).
%-----------------------------------------------------------------------------%
More information about the users
mailing list