[m-users.] [Beginner] Fixing a type error in parameter of foldl

Zoltan Somogyi zoltan.somogyi at runbox.com
Sat Oct 15 20:15:23 AEDT 2022



On Sat, 15 Oct 2022 14:14:07 +0530, Razetime <rraghu.11502 at gmail.com> wrote:
> This is my program (spoilers for advent of code 2016 day 2):
> 
> :- module a02.
> 
> :- interface.
> :- import_module io.
> :- pred main(io::di,io::uo) is det.
> :- type dir ---> u;d;l;r.
> 
> :- implementation.
> :- import_module int,string,list,require.
> 
> :- pred p1(list(dir)::in,int::in,int::out) is det.
> p1(D,S,F):-foldl(turn,D,S,F).
>
> ...
>
> however, the types of this predicate 'turn' do not coincide with the
> types for foldl and I do not understand why. I do not understand why
> the character type is expected in the first slot.

It is one possible expectation, because you have not told the compiler
*which* foldl predicate you want to invoke. You have imported two
modules that both define a predicate named foldl, list and string.
The first expected type is the type of list.foldl, the second expected type
is the type of string.foldl, which executes an operation on each *character*
of its input string. If you replace just "foldl" with "list.foldl" above,
you get just one expected type.

I enclose below the code which I reformatted to follow our usual style,
which I think is signicantly easier to read.

Zoltan.

:- module a02x.

:- interface.
:- import_module io.

:- pred main(io::di, io::uo) is det.

:- implementation.

:- import_module int.
:- import_module string.
:- import_module list.
:- import_module require.

:- type dir
    --->    u
    ;       d
    ;       l
    ;       r.

:- pred p1(list(dir)::in, int::in, int::out) is det.

p1(D, S, F) :-
    list.foldl(turn, D, S, F).

:- pred turn(int::in, dir::in, int::out) is det.

turn(S, l, E) :- ( if S rem 3 = 0 then E = S else E = S-1 ).
turn(S, r, E) :- ( if S rem 3 = 2 then E = S else E = S+1 ).
turn(S, u, E) :- ( if S // 3 = 0 then E = S else E = S-3 ).
turn(S, d, E) :- ( if S // 3 = 2 then E = S else E = S+3 ).

:- pred char_dir(character::in, dir::out) is det.

char_dir('U', u).
char_dir('D', d).
char_dir('L', l).
char_dir('R', r).
char_dir(_, _) :-
    unexpected($pred, "'dir").

main(!IO):-
    io.read_named_file_as_lines("inp/02", ReadResult, !IO),
    (
        ReadResult = ok(Lines),
        list.map(dir_string_to_dirs, Lines, ListOfDirLists),
        io.print_line(ListOfDirLists, !IO)
    ;
        ReadResult = error(Error),
        io.print_line(Error, !IO)
    ).

:- pred dir_string_to_dirs(string::in, list(dir)::out) is det.

dir_string_to_dirs(String, Dirs) :-
    string.to_char_list(String, Chars),
    list.map(char_dir, Chars, Dirs).




More information about the users mailing list