Yes,
covariant/contravariant is a very good hint. I had not known these terms. You are always a great source of information.
Like you said, a predicate type is
covariant in the type of its output arguments. It seems however that by the semantics "
a predicate which given any subtype Dom of integer returns a value in that type" of
where Dom supports integer, predicate
qA is treated
contravariant in the
Dom output argument.
The result of contravariance in an output argument is that bounded polymorphism is not applicable to output parameters at all. I have tried all (below three) cases to apply it to object output arguments, but the compiler refuses them all:
Code: Select all
interface superType
end interface superType
class superType : superType
end class superType
implement superType
end implement superType
%===
interface subType supports superType
end interface subType
class subType : subType
end class subType
implement subType
end implement subType
%===
implement main
class predicates
oA : (Type O [out])
where Type supports superType.
clauses
oA(O) :-
O = subType::new(). % super/sub
%---
class predicates
oB : (Type O [out])
where Type supports subType.
clauses
oB(O) :-
O = superType::new(). % sub/super
%---
class predicates
oC : (Type O [out])
where Type supports superType.
clauses
oC(O) :-
O = superType::new(). % super/super
Hence my conclusion is: With the current semantics (the one you stated)
p from my initial examples is the bug, while the errors in
p1 and
p2 are correct. But the semantics should be changed, so that bounded polymorphism can also be used on output parameters.