How to declare a pred for a predicate that imports or outputs lists?

96 views Asked by At

Looking for help declaring a pred for a predicate that imports or outputs lists. I tried :- pred name(list::in, integer::out) is multi. and compiler error message says that list/0 isn't recognized. Checked library module list and see that I should write something like ...(list(T)::in . . . ), but didn't fully understand what to do.

2

There are 2 answers

0
Paul Bone On BEST ANSWER

List is a parametric type, parametric types take one or more parameters. In the case of list the parameter says what this is a list of. You may have a list of numbers, a list of strings, a list of pumpkins or a list of lists of numbers (any valid type). So, if I create a function such as:

:- func max(list(int)) = int.

This function takes a list of ints and returns an int (the maximum number found in the list).

So, what's with list(T)? A token beginning with a capital letter is a variable, even in types, It can stand for any other type (usually). So "list(T)" means a list of anything, such as a list of numbers or strings. The next predicate is polymorphic, it works for different types depending on the actual values of it's type variable.

:- pred first(list(T)::in, T::out) is semidet.

A list of anything can be passed as the first item in the list will be returned, if there is one. If this is used with a list of strings "list(string)" then T will be substituted (during compilation) with "string".

The reference for this part of Mercury's type system is here. http://www.mercurylang.org/information/doc-release/mercury_ref/Discriminated-unions.html#Discriminated-unions

0
dogwood On

I have tried :- pred name(...list(T),....) is ... and the compiler is no longer reporting errors related to my pred declaration. Don't yet know that the results will be correct, but one step closer.