[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