Эрланг: можно ли написать минимальную функцию в виде списка? - PullRequest
5 голосов
/ 02 марта 2011

С учетом функции:

min(A, B)  when A =< B -> A;
min(_A, B)             -> B.

могу ли я использовать это в функции foldl аналогично этому:

lists:foldl(fun min/2, 0, [1,2,3,4,5,6,7,8,9,10])

Я считаю, что это невозможно, потому чтоЯ должен установить начальное значение, которое будет сравниваться с остальной частью списка, например, нет функции идентификации, о которой я мог бы думать.Я прав?

Синтаксис написан на Erlang, но должен быть читаем и для не-Erlang программистов.

Ответы [ 3 ]

11 голосов
/ 02 марта 2011
min(List) ->
    Min = fun(A,  B) when A < B -> A;
             (_A, B)            -> B end,
    lists:foldl(Min, undefined, List).

Использование undefined в качестве исходного состояния должно помочь. Возвращает undefined для пустого списка, что неплохо как API.

Если вы хотите, чтобы он падал в пустом списке, используйте вместо этого заголовок функции:

min([Head|Rest]) ->
    Min = fun(A,  B) when A < B -> A;
             (_A, B)            -> B end,
    lists:foldl(Min, Head, Rest).
5 голосов
/ 02 марта 2011
1> List = [42,13,25,3,19,20].
[42,13,25,3,19,20]
2> lists:foldl(fun(X, Y) -> erlang:min(X,Y) end, hd(List), tl(List)).   
3

Завершает работу программы в пустом списке. Рекомендуемый подход - «пусть она рушится», а не защитное программирование.

2 голосов
/ 04 марта 2011

Предложение Адама Линдберга об использовании undefined в качестве начального значения имеет тот недостаток, что он генерирует странные результаты для списков, в которых атомы являются членами.Erlang имеет глобальный порядок всех объектов, поэтому хорошее свойство функции min было бы пригодно для всех типов.

Я думаю, что более разумно разбивать пустой список.Разница в том, что клиент должен беспокоиться о деле, а не о том, чтобы получить undefined в качестве результата.

...