lists:mapfind?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
22 messages Options
12
Reply | Threaded
Open this post in threaded view
|

lists:mapfind?

Max Lapshin-2
We have lists:keyfind, but are there any plans for lists:mapfind?



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Dmytro Lytovchenko
A good first step would be to make a ticket on bugs.erlang.org
This isn't a primary source of tasks for OTP team but one of the contributors might like it.

A good second step would be for someone to write it.

2017-08-18 11:08 GMT+02:00 Max Lapshin <[hidden email]>:
We have lists:keyfind, but are there any plans for lists:mapfind?



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Lukas Larsson-8
In reply to this post by Max Lapshin-2
I've been thinking of adding that and also lists:mapsort, and while at it we should probably also add lists:mapdelete, lists:mapmap and the others.

The reason I haven't spent much effort in adding them is because I'm not sure the lists module is the correct place to put them and also I'm unsure about their general usefulness.

Lukas

On Fri, Aug 18, 2017 at 11:08 AM, Max Lapshin <[hidden email]> wrote:
We have lists:keyfind, but are there any plans for lists:mapfind?



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Max Lapshin-2
In reply to this post by Dmytro Lytovchenko
Ok.

So I wanted to hear something like:

a) it is already written, wait a bit
b) not written but a good idea: spend some time and write it
c) bad idea, will not accept it even if you write it.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Lukas Larsson-8
We do like the idea, however some time has to be spent on figuring out what the best API would be.

ListOfMaps = [#{ key => 1}, #{ key => 2}],
#{ key => 2 } == lists:keyfind(fun(#{ key := V }) -> V end, 2, ListOfMaps).

#{ key => 2 } == lists:keyfind(key, 2, ListOfMaps).

#{ key => 2 } == lists:find(fun(#{ key := V }) -> V end, 2, ListOfMaps).

#{ key => 2 } == lists:mapfind(key, 2, ListOfMaps).

#{ key => 2 } == maps:findinlist(key, 2, ListOfMaps).

Maybe there are other, better ideas?

My preferences are either lists:keyfind with a fun, or lists:mapfind. I like lists:keyfind with a fun as it is more general, and allows me to use any container within a list, it is however not as clear is lists:mapfind in what the function does.

Also as I stated before, if we add calls for find, we should also add calls for the other variations of the function.

On Fri, Aug 18, 2017 at 11:23 AM, Max Lapshin <[hidden email]> wrote:
Ok.

So I wanted to hear something like:

a) it is already written, wait a bit
b) not written but a good idea: spend some time and write it
c) bad idea, will not accept it even if you write it.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Håkan Mattsson
In reply to this post by Lukas Larsson-8

Are really the lists module the natural home for these functions? Would not the maps module be a better choice?

/Håkan

On Fri, Aug 18, 2017 at 11:23 AM, Lukas Larsson <[hidden email]> wrote:
I've been thinking of adding that and also lists:mapsort, and while at it we should probably also add lists:mapdelete, lists:mapmap and the others.

The reason I haven't spent much effort in adding them is because I'm not sure the lists module is the correct place to put them and also I'm unsure about their general usefulness.

Lukas

On Fri, Aug 18, 2017 at 11:08 AM, Max Lapshin <[hidden email]> wrote:
We have lists:keyfind, but are there any plans for lists:mapfind?



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Roger Lipscombe-2
In reply to this post by Lukas Larsson-8
On 18 August 2017 at 11:20, Lukas Larsson <[hidden email]> wrote:
> We do like the idea, however some time has to be spent on figuring out what
> the best API would be.

What's wrong with plain ol' lists:filter/2?
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

zxq9-2
On 2017年08月18日 金曜日 13:58:01 Roger Lipscombe wrote:
> On 18 August 2017 at 11:20, Lukas Larsson <[hidden email]> wrote:
> > We do like the idea, however some time has to be spent on figuring out what
> > the best API would be.
>
> What's wrong with plain ol' lists:filter/2?

Good point.

What are the cases not covered by the lists module?
filter/2, partition/2, matching/guarded list comprehensions, etc?

I'm not trying to say there are no such cases or that an improvement
can't be made -- I just can't think of a situation off the top of
my head that would be served by something like lists:mapfind/3,4.

-Craig
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Richard A. O'Keefe-2
In reply to this post by Lukas Larsson-8


On 18/08/17 9:23 PM, Lukas Larsson wrote:
> I've been thinking of adding that and also lists:mapsort, and while at
> it we should probably also add lists:mapdelete, lists:mapmap and the others.
>
> The reason I haven't spent much effort in adding them is because I'm not
> sure the lists module is the correct place to put them and also I'm
> unsure about their general usefulness.

Three observations:

  (1) lists: is absolutely the wrong place for them.
      They belong in the maps: module, where you can find
      maps:filter(Pred, Map1) -> Map2
 >>>> maps:find(Key, Map) -> {ok,Value} | error
      maps:fold(Fun, Init, Map) -> Acc
      ...
      Anybody who wants these functions is most certainly
      going to look for them there first.

      Putting the functions in maps: means you don't have
      to stick 'map' in their names.

  (2) The names give me only the vaguest idea of what the
      functions are supposed to do.  For example, how is
      mapdelete different from maps:take/2?  lists:delete/2
      removes the first copy of its first argument; for
      maps, does this look for a value, a key, or a pair?
      How would lists:mapfind have differed from maps:find/2?

  (3) Given that maps:to_list(Map) -> [{Key,Value}]
      and maps:from_list(List_Of_Pairs) -> Map
      exist, additional functions on maps can be prototyped
      by anyone who wants them in plain Erlang.

      Presumably

      map(Fun, Map) ->
          maps:from_list([{K,Fun(K,V)} || {K,V} <- maps:to_list(Map)]).

      Let's try three variants of delete/2.

      keydelete(Key, Map) ->
          case maps:take(Key, Map)
            of {_,Map1} -> Map1
             ; error    -> Map
          end.

      valuedelete(Value, Map) ->

      Sorry, the definition just fell apart.  In a map, which is
      the "first" pair with a matching value?  Something that
      deletes *all* pairs with matching values, no problem.
      Just use filter.  But the first?

      pairdelete(Key, Value, Map) ->
          maps:filter(fun (K, V) -> K == Key and V == Value end, Map).

It would be a very good thing when proposing a new library
function to provide

  - a specification of what it should do

  - ideally, a reference implementation in Erlang

  - a use case.

Sometimes, of course, it would be very difficult to write the
reference implementation, and sometimes the point of proposing
a new function is to discuss what its specification should be.

Ah.  It just occurred to me that maybe lists:mapfind was meant
to be lists:mapfind/3 with an interface like

     mapfind(Value, Key, MapList) ->
         the first Map in MapList having a pair Key := Value
         or false if there is no such Map.

     % in maps:, so no maps: prefixes.

     find_in_list(Value, Key, [Map|MapList]) ->
         case find(Key, Map)
           of {ok, Value} -> Map
            ; error       -> find_in_list(Value, Key, MapList)
         end;
     find_in_list(_, _, []) ->
         false.

But I am left wondering why this particular combination is so
important.  Suppose instead we add this function to lists:.

%   first(Pred, List) -> {ok, Value} | error
%   Types
%      Value = T
%      List = [T]
%      Pred = fun(T -> boolean())
%
%   If there is a Value in List such that Pred(Value),
%   returns {ok,Value} for the first such Value,
%   otherwise returns error.

first(Pred, [X|Xs]) ->
     case Pred(X)
       of true  -> {ok,X}
        ; false -> first(Pred, Xs)
     end;
first(_, []) ->
     error.

Now find_in_list(Value, Key, MapList) ->
         lists:first(fun (Map) ->
             maps:is_key(Key, Map) andalso maps:get(Key, Map) == Value
          end, MapList).

And now we see the primitive we really want:

%   has_key(Key, Map, Value) -> boolean()
%   Types
%       Key = term()
%       Map = #{}
%       Value = term()
%   Returns true when Map contains Key as a key and associates
%   Value with that key, otherwise false.
%   The call fails with a {badmap,Map} exception if Map is not a map.

maps:has(Key, Map, Value) ->
     is_key(Key, Map) andalso get(Key, Map) == Value.

With that,
     find_in_list(Value, Key, MapList) ->
         lists:first(fun(Map) -> maps:has(Key, Map, Value) end, MapList).

I have found (the equivalent of) maps:has_key/3 very useful when
processing SGML and XML.  I have found (the equivalent of)
lists:first/2 so useful elsewhere that I was surprised to find it
missing from lists:.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Richard A. O'Keefe-2
In reply to this post by zxq9-2


On 19/08/17 1:04 AM, zxq9 wrote:
> Good point.
>
> What are the cases not covered by the lists module?
> filter/2, partition/2, matching/guarded list comprehensions, etc?

We have all(Pred, List)
         any(Pred, List)
     but one(Pred, List) is missing.

%   one(Pred, List) is true when List has exactly one element X
%   such that Pred(X) is true.  Yes, this is useful.

one(Pred, [X|Xs]) ->
     case Pred(X)
       of true  -> not(any(Pred, Xs))
        ; false -> one(Pred, Xs)
     end;
one(_, []) ->
     false.


%   first(Pred, List) returns {ok,Value} when Value is the
%   first element of List such that Pred(Value), or error
%   if there is no such value.

first(Pred, [X|Xs]) ->
     case Pred(X)
       of true  -> {ok,X}
        ; false -> first(Pred, Xs)
     end;
first(_, []) ->
     error.

%   last(Pred, List) returns {ok,Value} when Value is the
%   last element of List such that Pred(Value), or error
%   if there is no such value.

last(Pred, [X|Xs]) ->
     case Pred(X)
       of true  -> last_aux(Pred, Xs, X)
        ; false -> last(Pred, Xs)
     end;
last(_, []) ->
     error.

last_aux(Pred, [X|Xs], Y) ->
     case Pred(X)
       of true  -> last_aux(Pred, Xs, X)
        ; false -> last_aux(Pred, Xs, Y)
     end;
last_aux(_, _, Y) ->
     {ok, Y}.


%  foldl1(Fun, List) is a relative of foldl/3 used when
%  the function has no (representable) left identity,
%  such as max and min.  It is an error if List is empty.

foldl1(Fun, [X|Xs]) ->
     foldl(Fun, X, Xs).

foldr1 is also missing.

The whole scan{l,r}{,1} family are missing.

As mentioned several years ago, unfold/2 is missing.

unfold(Fun, State) ->
     case Fun(State)
       of {Head,State1} -> [Head | unfold(Fun, State1)]
        ; []            -> []
     end.

takewhile and dropwhile are there, and drop is there
under the name nthtail, but take is not there.

uniq(List) -> List'
uniq(Eql, List) -> List'
    returns a subsequence of List with *adjacent*
    duplicates dropped,  Whenever there is a run
    ...x1,x2,...,xn such that Eql(xk_1, xk) for
    2<=k<=n, x1 is included in the result and
    x2...xn are not.  The default equality function
    is exact equality.  O(length(List)).

nub(List) -> List'
nub(Eql, List) -> List'
    returns a subsequence of List with duplicates
    dropped.  Whenever there is a pair ...xi...xj...
    such that Eql(xi, xj), xj is excluded from the
    result.  The default equality function is
    exact equality.  O(length(List)**2).

group(List) -> List_Of_Lists
group(Eql, List) -> List_Of_Lists
    returns a list of lists whose concatenation
    is the original List.  If [...xi...xj...] is
    an element of the result, Eql(xi, xj).  The
    Eql function should be transitive but need not
    be an equivalence; the default is exact equality.
    O(length(List)).

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Max Lapshin-2
maps:listfind
maps:listtake
maps:listpartition

so?

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Roger Lipscombe-2
In reply to this post by Richard A. O'Keefe-2
On 20 August 2017 at 23:46, Richard A. O'Keefe <[hidden email]> wrote:
>  (1) lists: is absolutely the wrong place for them.

The thing I missed at first is this:

In Lukas's suggestion, these are *list of maps*, and we're searching
the *list* for the *map* with the specified K/V pair. If we're dealing
with *lists* (of maps), then the 'lists' module is, at first glance, a
reasonable place to put this functionality.

It's unclear whether that's what Max was asking for. Max?

But: I don't believe we need it *at all*. Let's just generalise the
whole thing with a predicate, and call it done. I'd like to see some
of ROK's suggestions ('one', 'first', etc.) -- because I came from C#,
which has 'Single', 'First', etc., and I kinda miss them.

Cheers,
Roger.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Constantine Povietkin

21 авг. 2017 г., в 10:30, Roger Lipscombe <[hidden email]> написал(а):

because I came from C#,
which has 'Single', 'First', etc., and I kinda miss them.

In case of ‘Single’ and ‘First’ you can use erlang:hd() or [FirstOrSingle | _Tail].
If you can provide an example you are getting challenges with, it’ll be easier to suggest you the most suitable erlang way to solve it.
In my experiance: lists:fold[l/r], lists:map, lists:foreach are able to do any kind of jobs.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Roger Lipscombe-2
On 21 August 2017 at 08:38, Константин Поветкин <[hidden email]> wrote:
> In case of ‘Single’ and ‘First’ you can use erlang:hd() or [FirstOrSingle |
> _Tail].

I was referring to Single and First with predicates, which aren't
quite the same (though can be built with) hd or [H | _].

My point is that I don't see the need for lists:mapfind (or whatever).
Is it a performance thing?
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Lukas Larsson-8
I agree with Richard that lists:first/2[1] is missing. Adding that functions could solve part of the problem. maps:has/3 could also be useful, though so far I've always found the same functionality to be easier to do with syntax.

For me, adding lists:mapfind/3 and friends to the stdlib is a convenience so that I don't end up writing the following in my projects:

%% Map helpers
mapsort(Key, Maps) ->
    lists:sort(fun(#{ Key := V1 }, #{ Key := V2 }) ->
                       V1 < V2
               end, Maps).

mapfind(Key, Value, List) ->
    lists:find(fun(#{ Key := V } ) -> V == Value end, List).

If it is only me and Max that find that we keep re-implementing these functions in various places, then I don't think that we should add special functions for list of maps. However as maps are gradually replacing more and more use-cases where before we used proplists or records, I think these functions will be become increasingly useful. I could very well be wrong though.

As for the naming of the functions, I don't have any great suggestions about what they should be called or where they should be placed. I don't find the lists module to be a very wrong place to put them (for the reason Roger pointed out), the maps module also makes some sense, or possibly adding a new module all together.

[1]: though I think it should be called lists:find/2 for consistency with lists:keyfind/3 and to not be confused as the opposite of lists:last/1


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Richard A. O'Keefe-2
In reply to this post by Roger Lipscombe-2


On 21/08/17 7:30 PM, Roger Lipscombe wrote:
> On 20 August 2017 at 23:46, Richard A. O'Keefe <[hidden email]> wrote:
>>  (1) lists: is absolutely the wrong place for them.
>
> The thing I missed at first is this:
>
> In Lukas's suggestion, these are *list of maps*, and we're searching
> the *list* for the *map* with the specified K/V pair. If we're dealing
> with *lists* (of maps), then the 'lists' module is, at first glance, a
> reasonable place to put this functionality.

The problem is that lists are such a general-purpose data structure.
Suppose we had an analogue of select(2) that took a list of io devices
and returned one of them that was ready, would we put that in the
lists: module or would we expect it to be in io:?

For me, the important thing is not whether the elements are
held in a list or a tuple or a set or whatever but what are
the focal things we're acting on.

Of course, this is arguably an instance of the expression problem,
and such there may be no best answer.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Richard A. O'Keefe-2
In reply to this post by Constantine Povietkin


On 21/08/17 7:38 PM, Константин Поветкин wrote:
>
>> 21 авг. 2017 г., в 10:30, Roger Lipscombe <[hidden email]
>> <mailto:[hidden email]>> написал(а):
>>
>> because I came from C#,
>> which has 'Single', 'First', etc., and I kinda miss them.
>
> In case of ‘Single’ and ‘First’ you can use erlang:hd() or
> [FirstOrSingle | _Tail].

That doesn't do one/2.
And it does first/2 at the expense of extra work, by a possibly
very large ratio.

> If you can provide an example you are getting challenges with, it’ll be
> easier to suggest you the most suitable erlang way to solve it.
> In my experiance: lists:fold[l/r], lists:map, lists:foreach are able to
> do any kind of jobs.

Those functions cannot stop early.  all/2 and any/2 can, of course,
but they cannot return a non-Boolean result.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Stanislaw Klekot
In reply to this post by Richard A. O'Keefe-2
On Tue, Aug 22, 2017 at 01:13:12PM +1200, Richard A. O'Keefe wrote:

> On 21/08/17 7:30 PM, Roger Lipscombe wrote:
> >On 20 August 2017 at 23:46, Richard A. O'Keefe <[hidden email]> wrote:
> >> (1) lists: is absolutely the wrong place for them.
> >
> >The thing I missed at first is this:
> >
> >In Lukas's suggestion, these are *list of maps*, and we're searching
> >the *list* for the *map* with the specified K/V pair. If we're dealing
> >with *lists* (of maps), then the 'lists' module is, at first glance, a
> >reasonable place to put this functionality.
>
> The problem is that lists are such a general-purpose data structure.
> Suppose we had an analogue of select(2) that took a list of io devices
> and returned one of them that was ready, would we put that in the
> lists: module or would we expect it to be in io:?

This one is easy: `io' module, because the primary focus is not
data structure manipulation, but reading or writing.

Actually, I initially thought the mapfind() function to be more like
map() + find() (a.k.a. filter()). It's not uncommon for me to want to
combine map() and some other operation. I treat lists:keyfind() as
a function that would normally belonged to proplists module, except that
it's mainly intended for 3+ tuples.

[select(2) analogue that works with lists]
> For me, the important thing is not whether the elements are
> held in a list or a tuple or a set or whatever but what are
> the focal things we're acting on.
>
> Of course, this is arguably an instance of the expression problem,
> and such there may be no best answer.

Well, at least two people agree on what to expect in this case.

--
Stanislaw Klekot
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Michael Truog
In reply to this post by Richard A. O'Keefe-2
On 08/21/2017 06:13 PM, Richard A. O'Keefe wrote:

>
>
> On 21/08/17 7:30 PM, Roger Lipscombe wrote:
>> On 20 August 2017 at 23:46, Richard A. O'Keefe <[hidden email]> wrote:
>>>  (1) lists: is absolutely the wrong place for them.
>>
>> The thing I missed at first is this:
>>
>> In Lukas's suggestion, these are *list of maps*, and we're searching
>> the *list* for the *map* with the specified K/V pair. If we're dealing
>> with *lists* (of maps), then the 'lists' module is, at first glance, a
>> reasonable place to put this functionality.
>
> The problem is that lists are such a general-purpose data structure.
> Suppose we had an analogue of select(2) that took a list of io devices
> and returned one of them that was ready, would we put that in the
> lists: module or would we expect it to be in io:?
>
> For me, the important thing is not whether the elements are
> held in a list or a tuple or a set or whatever but what are
> the focal things we're acting on.
>
> Of course, this is arguably an instance of the expression problem,
> and such there may be no best answer.
>

I agree that these functions should not be added to the lists module, since it already has many functions that do not need to be confused with newer additions (new functions confused with lists:keymap/3, lists:map/2, lists:mapfoldl/3, lists:mapfoldr/3, simply due to the word "map" that doesn't relate to map elements). I understand the lists module already has functions for handling lists that contain tuples with the "key" functions.

In my mind, this argues for adding the concept of a namespace to Erlang source code, so that ".map:" or ".maps:" can be used as a suffix on lists, to show that the functions relate to lists that contain maps.  I understand the past concept of Erlang packages failed and was gradually removed.  Also, I understand there is the common response that you can always put periods in module names, similar to how elixir modules have an "Elixir." module name prefix for beam output.  The current situation is unable to easily manage complexity as the SLOC of Erlang source code grows, artificially limiting the size of Erlang codebases, and the dependencies they may be able to manage (with the additional problem of being unable to utilize more than 1 version of the same dependency).  I believe this hesitation to add more complexity to the single "lists" module is evidence of a problem, and the need for more hierarchical organization of source code, even if it only results in periods in
module names.

Best Regards,
Michael


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: lists:mapfind?

Richard A. O'Keefe-2
In reply to this post by Lukas Larsson-8


On 22/08/17 4:18 AM, Lukas Larsson wrote:
> I agree with Richard that lists:first/2[1] is missing.

> [1]: though I think it should be called lists:find/2 for consistency
> with lists:keyfind/3 and to not be confused as the opposite of lists:last/1

lists:first/2 is the opposite of lists:last/2.

I thought I included that.  If not,

last(Pred, [X|Xs]) ->
     case Pred(X)
       of true  -> last_aux(Pred, Xs, X)
        ; false -> last(Pred, Xs)
     end;
last(_, []) ->
     error.

last_aux(Pred, [X|Xs], Y) ->
     last_aux(Pred, Xs, case Pred(X)
                          of true  -> X
                           ; false -> Y
                        end);
last_aux(_, [], Y) ->
     {ok, Y}.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
12