Ошибка исключения Erlang при использовании BIF и lists:maps

Нашей задачей было написать функцию normalize/1, которая делит каждый элемент списка на мой максимальный элемент.

Вот мой код до сих пор (вместо моей собственной написанной функции я использовал встроенную, чтобы найти максимум):

normalize(List) -> 
    Z = lists:max(List),
    [ X / Z  || X  <- List].

Теперь мне нужно написать функцию normalize2, которая делает то же самое, что и normalize/1, но использует lists:map/2.

normalize2(List) -> lists:map(fun normalize/1, List).

Терминал показывает это:

тест3: нормализовать2 ([1,2,3,5]). ** ошибка исключения: нет соответствующих списков функций: max(1) (lists.erl, строка 313) в функции test3:normalize/1 (test3.erl, строка 85) при вызове из lists:map/2 (lists.erl , строка 1224)

ОБНОВИТЬ:

Здесь find_max/1:

find_max([T]) ->
    T;
find_max([H,H1|T]) when H > H1->
    find_max([H,T]);
find_max([_H,H1|T])->
    find_max([H1|T]).

Если я использовал ^ find_max, терминал показывает мне:

тест3: нормализовать2 ([1,2,3,5]). ** ошибка исключения: нет функционального предложения, соответствующего test3:find_max(1) (test3.erl, строка 137) в функции test3:normalize/1 (test3.erl, строка 84) при вызове из lists:map/2 (lists.erl , строка 1224)

Строка 137: find_max([T]) -> T; Строка 84: Z = find_max(List),


person Gabriele    schedule 17.09.2014    source источник
comment
Если бы я использовал свою собственную функцию find_max/1 в normalize/1, она показала бы мне ту же ошибку, но вместо списков соответствий предложения функции: max(1) это не списки соответствия предложения функции: max(1,0).   -  person Gabriele    schedule 17.09.2014


Ответы (2)


lists:max возвращает максимальное значение из списка. Это означает, что аргумент этой функции должен быть списком.

Когда вы вызываете lists:map, это означает -- применить некоторую функцию ('normailze' в вашем случае) к каждому элементу списка. Но элементы списка являются целыми числами. Вот почему строка Z=lists:max(List) выдает исключение (на самом деле переменная List не является списком).

вы можете использовать lists:map в качестве замены понимания списка. Вроде

normalize2(List) -> Z = lists:max(List), lists:map( fun(X) -> X/Z end, List).
person Odobenus Rosmarus    schedule 17.09.2014
comment
Если мой ввод [1,2,3,4] и я использовал find_max/1, он дает мне ответ, подобный [4]. Если бы я использовал это для normalize2, как я написал выше, я получаю это в терминале: test3:normalize2([1,2,3,4]). ** ошибка исключения: нет функционального предложения, соответствующего test3:'-normalize/1-lc$^0/1-0-'(1) (test3.erl, строка 86) в списках функций:map/2 (lists.erl, строка 1224) - person Gabriele; 17.09.2014
comment
1) что такое find_max? 2) как вы его использовали? 3) было бы лучше, если бы вы предоставили весь test3.erl - person Odobenus Rosmarus; 17.09.2014
comment
Большое спасибо за ваш ответ. Я хотел бы проголосовать за ваш ответ, но у меня пока недостаточно очков репутации. Еще раз спасибо. - person Gabriele; 23.09.2014

Поскольку вы уже выяснили, как использовать понимание списка в normalize/1, вероятно, нет смысла писать «другое» решение с использованием lists:map/2.

Обязательно выработайте ментальный рефлекс, чтобы всегда мгновенно заменять любое использование lists:map/2 красивым пониманием списка!

person aronisstav    schedule 17.09.2014
comment
Это почему? Это потому, что его легче читать, или мне не хватает какой-то информации? - person Gabriele; 17.09.2014
comment
Никакой другой причины, на самом деле. lists:map/2 эквивалентно пониманию и позволяет избежать написания анонимной функции. - person aronisstav; 18.09.2014