listdeclarationpredicatemercury

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


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.


Solution

  • 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