[erlang-questions] To name a function

Raimo Niskanen raimo+erlang-questions@REDACTED
Thu Dec 16 17:50:28 CET 2010


On Thu, Dec 16, 2010 at 09:06:46AM -0600, David Mercer wrote:
> On Thursday, December 16, 2010, Attila Rajmund Nohl wrote:
> 
> > 2010/12/16, Morten Krogh <mk@REDACTED>:
> > > As soon as you have seen both an element that satisfies the condition
> > > and one that doesn't, you can return "some", making a full list
> > > traversal overkill for many inputs.
> > 
> > Now that's a good idea:
> > 
> > has_property(Fun, [E | Rest]) ->
> >     has_property(Fun, Fun(E), Rest).
> > 
> > has_property(_Fun, Prev, []) ->
> >     case Prev of
> > 	true -> all;
> > 	false -> none
> >     end;
> > 
> > has_property(Fun, Prev, [E | Rest]) ->
> >     Curr = Fun(E),
> >     case Curr of
> > 	Prev -> has_property(Fun, Prev, Rest);
> > 	_ -> some
> >     end.
> 
> I was thinking a throw would be appropriate for the early-out:
> 
> has_property(F, L) ->
> 	catch lists:foldl(fun(X, Stat) -> case {F(X), Stat} of
> 	                                  	{true, empty} -> all;
> 	                                  	{true, all} -> all;
> 	                                  	{true, none} -> throw(some);
> 	                                  	{false, empty} -> none;
> 	                                  	{false, all} -> throw(some);
> 	                                  	{false, none} -> none
> 	                                  end
> 	                  end,
> 	                  empty, L).

Preparing a catch and cleaning up is more expensive than just returning a
value. Here is a shorter variant (also not tested) of Pierpaolo Bernardi's
suggestion, returning true | false | ambivalent.

categorize(P, []) when is_function(P, 1) ->
  ambivalent;
categorize(P, [X|Xs]) ->
  case P(X) of
    true ->
      lists:all(P, Xs) orelse ambivalent;
    false ->
      lists:any(P, Xs) andalso ambivalent;
  end.

With these return values Attila Rajmund Nohl's suggestion also gets shorter:

categorize(P, []) when is_function(P, 1) ->
  ambivalent;
categorize(P, [X|Xs]) ->
  case P(X) of
    Bool when is_boolean(Bool) ->
      categorize(P, Xs, P(X))
  end.

categorize(P, [], Bool) ->
  Bool;
categorize(P, [X|Xs], Bool) ->
  case P(X) of
    Bool ->
      categorize(P, Xs, Bool);
    Other when is_boolean(Other) ->
      ambivalent
  end.

Also not tested.

> 
> 
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


More information about the erlang-questions mailing list