[erlang-questions] newbie: how to ignore the rest in a variable length tuple?

Håkan Stenholm hokan.stenholm@REDACTED
Sat Mar 1 00:59:33 CET 2008


Anthony Kong wrote:
> Hi, all,
>
> What I want to achieve is this:
>
> In the case I received a tuple like {x, B, C, D} I want to perform
> some action using B, C, D.
>
> But if I received a tuple like {y, ...} I just don't care the rest of
> data in the tuple.
>
> So, I tried a syntax {y, _}, but this led to a function_clause
> exception. It is because erl applies this to a tuple of 2 elements,
> not "tuple of any length with first element == y".
>
> Is there any alternative to "{y, _, _, _} " ?
>   

Sorry, there isn't any special syntax for checking "tuple starts with", 
but there are several alternate approaches:

* Restructure your data to conform to something like {Type, PayLoad}, so 
that {y, A, B} becomes {y, {A, B}}. All "y" tuples are then of the same 
length, so that you can use a single pattern {y, _}.

* check individual tuple fields, like this:

case element(1, Tuple)  of
    x -> ...
    y -> ...
end

* convert the tuple to a list, and match using the list:

case tuple_to_list(Tuple)  of
    [x| ...] -> ...
    [y| ...] -> ...
end

* Specifying a new clause for each valid pattern, is useful to ensure 
that only valid inputs are accepted. If the input should be ignored you 
could simply drop it.

f({x, B, C, D) ->
    .... ; % do stuff
f(_) ->
    ok. % ignore non-x tuple or x tuples of length /= 4

or only keep the first clause and crash on unexpected input:

f({x, B, C, D) ->
    .... . % do stuff


> Because of the way I construct the messages, it can be a tuple of 4 or
> 5 elements.  That means If I have to define a clause for {y, _, _, _}
> then I have to also define another one for {y, _, _, _, _}. I am
> looking for a leaner expression.
>
>
> Cheers, Anthony
>
> ====================================
>
> -module(c1).
>
> -export([test/0]).
> test() ->
>   R = c1({x, b, c, d}),
>   io:format("~p~n", [R]),
>   R1 = c1({y, b, c, d}),
>   io:format("~p~n", [R1]).
>
>
> c1({x, B, C, D}) ->
>   io:format("~p ~p ~p~n", [B, C, D]),
>   {ok, get_x};
>
> c1({y, _}) ->
>     {ok, get_y}.  %% throw function_clause exception
>
> ====================================
>
>
>
>   



More information about the erlang-questions mailing list