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

Razetime rraghu.11502 at gmail.com
Sat Oct 15 20:33:12 AEDT 2022


Thanks for the help. I got a new error on this code but I managed to
figure it out. It is very confusing that the initial value argument of
list.foldl is not passed in as the first argument of the predicate,
but as the second argument. The expected type in this case shows which
arguments must have the same type, correct?

$ mmc --use-subdirs a02.m
a02.m:012: In clause for predicate `p1'/3:
a02.m:012:   in argument 1 of call to predicate `list.foldl'/4:
a02.m:012:   type error: argument has type
a02.m:012:     `pred(
a02.m:012:       int,
a02.m:012:       a02.dir,
a02.m:012:       int
a02.m:012:     )',
a02.m:012:   expected type was
a02.m:012:     `pred(
a02.m:012:       L,
a02.m:012:       A,
a02.m:012:       A
a02.m:012:     )'.



On 10/15/22, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
>
>
> 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