Given the following code…
-module(example).
-export([example/3]).
-export_type([acc/0]).
-record(acc, {last}).
-opaque acc() :: #acc{}.
-spec example([binary()], map(), acc()) -> acc().
-spec accumulator(Elem :: binary(), Extra :: map(), acc()) -> acc().
accumulator(Elem, _Extra, Acc) ->
Acc#acc{last = Elem}.
example(List, Extra, A0) ->
lists:foldl(fun(Elem, A1) -> accumulator(Elem, Extra, A1) end, A0, List).
…eqwalizer spits out all of the following…
error: incompatible_types
┌─ src/example.erl:13:5
│
13 │ lists:foldl(fun(Elem, A1) -> accumulator(Elem, Extra, A1) end, A0, List).
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│ │
│ lists:foldl(fun, A0, List).
Expression has type: term()
Context expected type: acc()
See https://fb.me/eqwalizer_errors#incompatible_types
│
term() is not compatible with acc()
because
term() is not compatible with #acc{}
error: incompatible_types
┌─ src/example.erl:13:46
│
13 │ lists:foldl(fun(Elem, A1) -> accumulator(Elem, Extra, A1) end, A0, List).
│ ^^^^ Elem.
Expression has type: term()
Context expected type: binary()
See https://fb.me/eqwalizer_errors#incompatible_types
error: incompatible_types
┌─ src/example.erl:13:59
│
13 │ lists:foldl(fun(Elem, A1) -> accumulator(Elem, Extra, A1) end, A0, List).
│ ^^
│ │
│ A1.
Expression has type: term()
Context expected type: acc()
See https://fb.me/eqwalizer_errors#incompatible_types
│
term() is not compatible with acc()
because
term() is not compatible with #acc{}
3 ERRORS
As far as I can tell, it fixates on all of the Acc :: term()
items in the spec for lists:foldl/3
, and doesn’t realise that acc()
is a term()
.
If I erase the types, by wrapping lists:foldl/3
…
foldl(Fun, Acc0, List) ->
lists:foldl(Fun, Acc0, List).
…then eqwalizer is happy. But that doesn’t seem particularly idiomatic.
Moreover, when I add a spec to my foldl
, to make use of type variables…
-spec foldl(Fun :: fun((Elem, Acc) -> Acc), Acc, [Elem]) -> Acc.
…eqwalizer doesn’t like that either.
Am I doing something wrong? Is eqwalizer doing something wrong? Are the typespecs on lists:foldl/3
wrong?