I've starting looking at the Mercury language, which seems very interesting. I'm a new to logic programming, but pretty experienced with functional programming in Scala and Haskell. One thing I've been pondering is why you need types in logic programming when you already have predicates which should be at least as expressive as types.
For example, what benefit is there to using types in the following snippet (taken from the Mercury tutorial):
:- type list(T) ---> [] ; [T | list(T)].
:- pred fib(int::in, int::out) is det.
fib(N, X) :-
( if N =< 2
then X = 1
else fib(N - 1, A), fib(N - 2, B), X = A + B
).
compared to writing it using only predicates:
list(T, []).
list(T, [H | X]) :- T(H), list(T, X).
int(X) :- .... (builtin predicate)
fib(N, X) :-
int(N),
int(X),
( if N =< 2
then X = 1
else fib(N - 1, A), fib(N - 2, B), X = A + B
).
Feel free to point to introductory material which covers this topic.
Edit: I probably was a bit unclear in the formulation of the question. I actually started looking at Mercury after looking into dependent typing languages like Idris, and the same way that values can be used in types in dependent typing, the same way predicates could be used at compilation time to verify the correctness of logic programs. I can see a benefit of using types for compile time performance reasons if the program takes a long time to evaluate (but only if the types are less complex than the "implementation" which is not necessarily the case when talking about dependent typing). My question is if there are other benefits to using types besides compile time performance.