Erlang: is it possible to write the minimum function as a list fold?
Given a function:
开发者_运维技巧min(A, B) when A =< B -> A;
min(_A, B) -> B.
can I use this in the function foldl
in a similar fashion to this:
lists:foldl(fun min/2, 0, [1,2,3,4,5,6,7,8,9,10])
I believe it is not possible, because I have to set an initial value that will be compared to the rest of the list, e. g. there is no identity function that I can think of. Am I right?
Syntax is written in Erlang, but should be readable for non Erlang programmers, too.
min(List) ->
Min = fun(A, B) when A < B -> A;
(_A, B) -> B end,
lists:foldl(Min, undefined, List).
Using undefined
as the initial state should do the trick. Returns undefined
for an empty list, which is kind of nice as an API.
If you want it to crash on an empty list, use this function header instead:
min([Head|Rest]) ->
Min = fun(A, B) when A < B -> A;
(_A, B) -> B end,
lists:foldl(Min, Head, Rest).
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
Crashes a program on an empty list, a recommended approach "let it crash" as opposed to defensive programming.
Adam Lindbergs proposal to use undefined
as initial value has the disadvantage that it generates weird results for lists that has atoms as members. Erlang has a global ordering of all objects, so a nice property of a min function would be to be usable for all types.
I think its more reasonable to crash on an empty list. The difference is that the client has to worry about the case, instead of having to worry about getting a undefined
as the result.
精彩评论