Initial post
I've been playing with swi-prolog for a several hours now and I got to dead end trying to mimic a simple polymorphic type system. So, before I have spent way to much time trying to get out, let me ask you guys a following question:
Say, I have declared relation named top
, that marks it`s single arg as a type.
top(nat). % naturals
top(list(T, _)) :- top(T). % polymorphic lists
and I also have classic Peano-like definition for Nats and somewhat reasonable definition for Lists:
nat(zero).
nat(s(A)) :- nat(A).
list(T, nil) :- top(T).
list(T, cons(T, _, _)) :- top(T)
at this point, the only thing left is an implementation for 'constructor' cons
. The most straightforward definition, that pops in my mind is
cons(T, A, B) :- top(T), list(T, B), T(A).
But, turns out, you cant have T(A)
in prolog. Is it because prolog is based on first order logic, where quantification over predicates is not available? If so, is there any workaround?
Update:
So, I ended up with a code like this:
top.
type(top, top).
type(top, nat).
type(top, container(T)) :- type(top, T).
type(top, either(A, B)) :- type(top, A), type(top, B).
type(nat, zero).
type(nat, s(A)) :- type(nat, A).
type(container(T), nil) :- type(top, T).
type(container(T), cons(Head, Tail)) :-
type(T, Head),
type(container(T), Tail).
type(either(A, _), left(V)) :- type(A, V).
type(either(_, B), right(V)) :- type(B, V).
which allows me to construct containers of values of any type, including the type top
- a type of types.
Thank you guys, cheers.
call(T,A)
orP=..[T,A],call(P)
, it's the same – CapelliCcons(T,A,B)
the type-checking predicate? You indeed cannot haveT
in predicate position because of FOL, but to checkA
for its type, it has to have its own type label, which must be somewhere in the term structure of A? As an example, Lambda Prolog has a type system but it's "behind the curtains", maybe you need a meta-interpreter? – David Tonhofer